rea-agents 3.2.1 → 4.0.1
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 +183 -332
- package/bridge/ghidra/ReaGhidraBridge.java +561 -74
- package/bridge/hopper_bridge.py +70 -27
- package/bridge/native/ReaNativeUI.swift +157 -0
- package/dist/application/AnalysisContextQueries.js +19 -5
- package/dist/application/AnalysisSnapshotCache.js +30 -11
- package/dist/application/AppleAssetCatalogAnalysis.js +171 -0
- package/dist/application/ArtifactExtractionDestination.js +0 -12
- package/dist/application/ArtifactGraphConstruction.js +44 -11
- package/dist/application/ArtifactInventory/classify.js +7 -15
- package/dist/application/ArtifactInventory/hash.js +4 -2
- package/dist/application/ArtifactInventory/policy.js +2 -17
- package/dist/application/ArtifactInventory/reader.js +3 -3
- package/dist/application/ArtifactInventory/scanCanonical.js +2 -2
- package/dist/application/ArtifactInventory/scanReader.js +12 -4
- package/dist/application/ArtifactInventory/types.js +0 -3
- package/dist/application/BinarySession.js +28 -43
- package/dist/application/BinarySessionExecution.js +37 -1
- package/dist/application/BinaryTargetResolver.js +50 -4
- package/dist/application/BrowserEvidence.js +36 -7
- package/dist/application/BrowserObservationService.js +17 -44
- package/dist/application/BrowserScenarioCaptureService.js +2 -35
- package/dist/application/BrowserScenarioEvidence.js +13 -9
- package/dist/application/CapabilityClientRequirements.js +2 -11
- package/dist/application/CapabilityInventory.js +21 -35
- package/dist/application/ClientConfigurationDocument.js +84 -7
- package/dist/application/ClientRegistrationIdentity.js +32 -0
- package/dist/application/ClientRegistrationStatus.js +59 -6
- package/dist/application/DirectAnalysis.js +37 -58
- package/dist/application/DirectAnalysisStatus.js +4 -4
- package/dist/application/Doctor.js +89 -80
- package/dist/application/DoctorDiagnostics.js +2 -26
- package/dist/application/DoctorScope.js +8 -14
- package/dist/application/ElectronActiveEvidence.js +10 -27
- package/dist/application/ElectronActiveObservationService.js +9 -36
- package/dist/application/ElectronBoundaryAnalysis.js +2 -0
- package/dist/application/ElectronBoundaryGraphNative.js +1 -1
- package/dist/application/ElectronEvidence.js +8 -3
- package/dist/application/ElectronObservationService.js +9 -25
- package/dist/application/EnhancedLiteralTracing.js +4 -8
- package/dist/application/EnhancedTools.js +15 -35
- package/dist/application/FilesystemSnapshot.js +7 -8
- package/dist/application/JavaScriptApplicationEvidenceGraph.js +2 -1
- package/dist/application/JavaScriptApplicationWorkflowService.js +31 -7
- package/dist/application/JavaScriptArtifactAnalysis.js +6 -4
- package/dist/application/JavaScriptArtifactFiles.js +5 -0
- package/dist/application/JavaScriptArtifactPathResolution.js +179 -47
- package/dist/application/JavaScriptRuntimeObservationEvidence.js +6 -3
- package/dist/application/JavaScriptRuntimeObservationService.js +9 -25
- package/dist/application/JavaScriptRuntimeReconciliationService.js +45 -4
- package/dist/application/JavaScriptSemanticGraphAsyncProjection.js +11 -0
- package/dist/application/JavaScriptSemanticGraphChildProcessProjection.js +11 -0
- package/dist/application/JavaScriptSemanticGraphDataProjection.js +11 -0
- package/dist/application/JavaScriptSemanticGraphFlowProjection.js +14 -5
- package/dist/application/JsonFiles.js +1 -1
- package/dist/application/LazyAnalysisProvider.js +27 -6
- package/dist/application/ManagedMemberComparisonService.js +19 -6
- package/dist/application/NativeApiInspection.js +2 -0
- package/dist/application/NativeCallRoutes.js +72 -0
- package/dist/application/NativeDispatchMetadataInspection.js +33 -0
- package/dist/application/NativeUiActionTrace.js +73 -49
- package/dist/application/NativeValueTrace.js +320 -0
- package/dist/application/ProcessCaptureCapability.js +32 -5
- package/dist/application/ProcessCaptureEnvironment.js +9 -26
- package/dist/application/ProcessCaptureError.js +1 -5
- package/dist/application/ProcessCaptureJournal.js +3 -40
- package/dist/application/ProcessCaptureLifecycle.js +102 -111
- package/dist/application/ProcessCli.js +18 -25
- package/dist/application/ProcessEvidence.js +5 -7
- package/dist/application/ProcessFilesystemEffects.js +36 -0
- package/dist/application/ProcessHarness.js +41 -120
- package/dist/application/ProcessNormalization.js +2 -17
- package/dist/application/ProcessScenarioRuntimeValidation.js +76 -0
- package/dist/application/ReferenceSourceImport.js +3 -4
- package/dist/application/Setup.js +236 -84
- package/dist/application/SetupClientConfiguration.js +14 -9
- package/dist/application/SetupPlan.js +138 -86
- package/dist/application/SetupSkill.js +0 -1
- package/dist/application/SupportedClients.js +102 -21
- package/dist/application/Uninstall.js +31 -20
- package/dist/application/Update.js +93 -0
- package/dist/application/UpdateMaintenance.js +108 -0
- package/dist/application/UpdateRuntime.js +126 -0
- package/dist/application/runtime.js +13 -2
- package/dist/artifacts/ArtifactPaths.js +6 -8
- package/dist/artifacts/ArtifactProvider.js +94 -41
- package/dist/artifacts/AsarArtifactReader.js +19 -4
- package/dist/artifacts/KeyedArchiveReader.js +110 -0
- package/dist/artifacts/MachOSliceArtifactReader.js +53 -5
- package/dist/artifacts/ZipArtifactReader.js +18 -1
- package/dist/browser/BrowserScenarioSecrets.js +28 -1
- package/dist/browser/CdpBrowserProvider.js +36 -15
- package/dist/browser/CdpCaptureDocuments.js +22 -8
- package/dist/browser/CdpCaptureEventHandlers.js +14 -5
- package/dist/browser/CdpCaptureEventHelpers.js +13 -0
- package/dist/browser/CdpCaptureEvents.js +10 -1
- package/dist/browser/CdpElectronInspection.js +5 -10
- package/dist/browser/CdpElectronProvider.js +1 -5
- package/dist/browser/CdpElectronScripts.js +1 -1
- package/dist/browser/CdpEndpoint.js +3 -2
- package/dist/browser/CdpObservationSession.js +14 -10
- package/dist/browser/CdpPageCapture.js +1 -1
- package/dist/browser/CdpPageCaptureScripts.js +1 -1
- package/dist/browser/CdpSafeMetadata.js +5 -4
- package/dist/browser/CdpScreenshot.js +16 -5
- package/dist/browser/CdpTargetSession.js +25 -4
- package/dist/browser/CdpWebMcpDiscovery.js +93 -20
- package/dist/browser/JavaScriptRuntimeScope.js +28 -2
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +9 -8
- package/dist/browser/PlaywrightElectronActiveActions.js +3 -10
- package/dist/browser/PlaywrightElectronActiveProvider.js +5 -5
- package/dist/browser/PlaywrightScenarioActions.js +1 -1
- package/dist/browser/PlaywrightScenarioArtifacts.js +13 -25
- package/dist/browser/PlaywrightScenarioBrowser.js +28 -25
- package/dist/browser/PlaywrightScenarioEvents.js +82 -93
- package/dist/browser/PlaywrightScenarioSession.js +27 -123
- package/dist/browser/PngVisualDiff.js +22 -3
- package/dist/browser/V8InspectorCaptureProjection.js +7 -1
- package/dist/browser/V8InspectorProvider.js +60 -7
- package/dist/browser/WebSourceMapFetcher.js +99 -53
- package/dist/cli/artifactCommands.js +56 -12
- package/dist/cli/coreAnalysisCommands.js +110 -0
- package/dist/cli/managedCommands.js +1 -31
- package/dist/cli/setupCommands.js +16 -14
- package/dist/cli/utilityCommands.js +61 -4
- package/dist/cli.js +5 -7
- package/dist/cliApplicationCommands.js +0 -83
- package/dist/cliBrowserAdvancedCommands.js +7 -11
- package/dist/cliBrowserCommands.js +15 -23
- package/dist/cliBrowserContext.js +3 -24
- package/dist/cliBrowserScenarioCommands.js +2 -10
- package/dist/cliCommandNames.js +82 -7
- package/dist/cliElectronCommands.js +10 -36
- package/dist/cliJavaScriptRuntimeCommands.js +6 -30
- package/dist/cliJsonInput.js +4 -2
- package/dist/cliLogging.js +16 -7
- package/dist/cliObservationOptions.js +1 -1
- package/dist/cliOutput.js +2 -4
- package/dist/cliProcessCommands.js +6 -33
- package/dist/cliSetup.js +90 -160
- package/dist/config/environment.js +2 -78
- package/dist/config/parseConfig.js +18 -109
- package/dist/config/parsers.js +0 -23
- package/dist/contracts/applicationToolContracts.js +1 -118
- package/dist/contracts/artifactToolContracts.js +11 -19
- package/dist/contracts/browserScenarioToolContracts.js +1 -5
- package/dist/contracts/browserToolContracts.js +9 -16
- package/dist/contracts/electronToolContracts.js +5 -6
- package/dist/contracts/enhancedInputs.js +3 -2
- package/dist/contracts/errorSchemas.js +16 -40
- package/dist/contracts/functionWorkflowToolContracts.js +2 -2
- package/dist/contracts/javascriptApplicationWorkflowExamples.js +2 -2
- package/dist/contracts/javascriptRuntimeObservationToolContracts.js +4 -4
- package/dist/contracts/javascriptRuntimeReconciliationExample.js +1 -1
- package/dist/contracts/managedToolContracts.js +7 -4
- package/dist/contracts/managedWorkflowExamples.js +0 -22
- package/dist/contracts/managedWorkflowToolContracts.js +16 -31
- package/dist/contracts/nativeToolContracts.js +9 -0
- package/dist/contracts/promptContracts.js +6 -6
- package/dist/contracts/sessionToolSchemas.js +3 -3
- package/dist/contracts/toolContractExamples.js +4 -3
- package/dist/contracts/toolContracts.js +18 -7
- package/dist/contracts/toolEffects.js +34 -21
- package/dist/contracts/toolOutputSchemaGroups.js +18 -5
- package/dist/contracts/toolOutputSchemaPrimitives.js +9 -6
- package/dist/contracts/toolSchemaMetadata.js +5 -8
- package/dist/doctorRuntime.js +0 -41
- package/dist/domain/analysisErrorPresentation.js +4 -28
- package/dist/domain/analysisErrorProjection.js +33 -50
- package/dist/domain/analysisProfile.js +1 -1
- package/dist/domain/analysisSnapshot.js +77 -3
- package/dist/domain/androidApplication.js +5 -4
- package/dist/domain/appleApplication.js +5 -4
- package/dist/domain/appleAssetCatalog.js +127 -0
- package/dist/domain/artifactComparison.js +7 -11
- package/dist/domain/artifactGraph.js +8 -6
- package/dist/domain/artifactInspection.js +13 -12
- package/dist/domain/binaryTarget.js +23 -9
- package/dist/domain/browserObservation.js +43 -24
- package/dist/domain/browserObservationSchemas.js +2 -1
- package/dist/domain/browserScenario.js +7 -107
- package/dist/domain/browserScenarioCapture.js +0 -1
- package/dist/domain/browserScenarioCaptureValues.js +5 -4
- package/dist/domain/browserScenarioDiff.js +1 -3
- package/dist/domain/browserScenarioValues.js +16 -107
- package/dist/domain/bundleComparison.js +18 -17
- package/dist/domain/callPathSchemas.js +17 -7
- package/dist/domain/changedBehavior.js +2 -3
- package/dist/domain/comparisonSemantics.js +19 -0
- package/dist/domain/completionLedgerGeneration.js +3 -2
- package/dist/domain/conformancePackage.js +2 -1
- package/dist/domain/conformanceTrustGate.js +3 -5
- package/dist/domain/customProtocolCapture.js +2 -2
- package/dist/domain/digests.js +30 -0
- package/dist/domain/dosMz.js +83 -0
- package/dist/domain/electronActiveObservation.js +7 -5
- package/dist/domain/electronObservation.js +3 -2
- package/dist/domain/electronStaticAnalysisNative.js +15 -6
- package/dist/domain/emptyArraySchema.js +3 -0
- package/dist/domain/errors.js +10 -28
- package/dist/domain/evidence.js +5 -3
- package/dist/domain/evidenceCompletionLedger.js +3 -2
- package/dist/domain/functionComparisonNormalization.js +24 -18
- package/dist/domain/functionComparisonResults.js +3 -7
- package/dist/domain/functionComparisonSchemas.js +3 -2
- package/dist/domain/hopperValues.js +108 -8
- package/dist/domain/javascriptApplicationAnalysis.js +4 -7
- package/dist/domain/javascriptApplicationEvidenceSchemas.js +4 -3
- package/dist/domain/javascriptApplicationGraphSchemas.js +8 -7
- package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +9 -7
- package/dist/domain/javascriptApplicationVersionItems.js +12 -18
- package/dist/domain/javascriptAstValues.js +4 -0
- package/dist/domain/javascriptExportShapeComparison.js +1 -6
- package/dist/domain/javascriptExportShapeComparisonSchemas.js +6 -10
- package/dist/domain/javascriptExportShapeVariants.js +15 -2
- package/dist/domain/javascriptFeatureTraceSchemas.js +8 -7
- package/dist/domain/javascriptRuntimeObservation.js +14 -2
- package/dist/domain/javascriptRuntimeReconciliationMatching.js +8 -0
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +4 -2
- package/dist/domain/javascriptRuntimeReconciliationResult.js +6 -4
- package/dist/domain/javascriptRuntimeReconciliationRuntime.js +15 -4
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +19 -18
- package/dist/domain/javascriptRuntimeStaticCandidates.js +18 -6
- package/dist/domain/javascriptSemanticAnalysis.js +57 -19
- package/dist/domain/javascriptSemanticAsyncEffects.js +39 -40
- package/dist/domain/javascriptSemanticCalls.js +46 -27
- package/dist/domain/javascriptSemanticChildProcesses.js +43 -50
- package/dist/domain/javascriptSemanticDataEffectHelpers.js +91 -18
- package/dist/domain/javascriptSemanticDataEffects.js +22 -10
- package/dist/domain/javascriptSemanticGraphSchemas.js +8 -6
- package/dist/domain/javascriptSemanticObjects.js +13 -3
- package/dist/domain/javascriptSemanticProjection.js +144 -38
- package/dist/domain/javascriptSemanticPromises.js +14 -27
- package/dist/domain/javascriptSemanticQuerySchemas.js +6 -9
- package/dist/domain/javascriptSemanticResources.js +2 -5
- package/dist/domain/javascriptSemanticState.js +4 -0
- package/dist/domain/javascriptSemanticTraceSchemas.js +2 -1
- package/dist/domain/javascriptSemanticTraversal.js +13 -5
- package/dist/domain/javascriptSemanticValues.js +10 -9
- package/dist/domain/javascriptSourceParser.js +5 -1
- package/dist/domain/javascriptStaticAnalysisCalls.js +8 -5
- package/dist/domain/javascriptStaticAnalysisHelpers.js +16 -7
- package/dist/domain/keyedArchive.js +181 -0
- package/dist/domain/managedApplicationGraph.js +4 -3
- package/dist/domain/managedArtifact.js +2 -1
- package/dist/domain/managedMemberComparison.js +18 -13
- package/dist/domain/managedMemberComparisonCoverage.js +2 -1
- package/dist/domain/managedMemberComparisonItems.js +27 -7
- package/dist/domain/managedMemberComparisonMatch.js +22 -6
- package/dist/domain/managedNativeVerificationMatch.js +2 -2
- package/dist/domain/managedNativeVerificationSchemas.js +7 -5
- package/dist/domain/managedReconstruction.js +6 -5
- package/dist/domain/nativeApiBoundary.js +7 -0
- package/dist/domain/nativeDataType.js +51 -0
- package/dist/domain/nativeInspection.js +0 -1
- package/dist/domain/nativeInstruction.js +82 -0
- package/dist/domain/nativeInvestigationGraph.js +9 -5
- package/dist/domain/nativeUiObservation.js +123 -0
- package/dist/domain/nativeValueFlow.js +17 -0
- package/dist/domain/nativeValueTrace.js +64 -0
- package/dist/domain/objcSwiftMetadata.js +39 -0
- package/dist/domain/peInspection.js +1 -0
- package/dist/domain/processCapture.js +5 -55
- package/dist/domain/processCaptureExample.js +0 -9
- package/dist/domain/processCaptureValidation.js +13 -144
- package/dist/domain/processComparison.js +3 -25
- package/dist/domain/processObservation.js +0 -29
- package/dist/domain/processScenario.js +28 -228
- package/dist/domain/processTraceDimensionProjection.js +0 -15
- package/dist/domain/processTraceEvaluation.js +0 -6
- package/dist/domain/protocolCapture.js +8 -36
- package/dist/domain/reconstructionCoverage.js +3 -2
- package/dist/domain/reconstructionObligationLedgerSchemas.js +4 -12
- package/dist/domain/reconstructionReadinessSchemas.js +4 -3
- package/dist/domain/reconstructionVerification.js +2 -1
- package/dist/domain/reconstructionVerificationSchemas.js +6 -13
- package/dist/domain/referenceSourceClassification.js +0 -110
- package/dist/domain/referenceSourceGraph.js +15 -5
- package/dist/domain/residualUnknown.js +3 -2
- package/dist/domain/runtimeIdentification.js +6 -5
- package/dist/domain/sourceMapContents.js +5 -0
- package/dist/domain/sourceToBundleComparison.js +3 -10
- package/dist/domain/sourceToBundleComparisonSchemas.js +7 -6
- package/dist/domain/sourceToBundleSignals.js +9 -3
- package/dist/domain/staticRuntimeCorrelation.js +5 -11
- package/dist/domain/webBundleAnalysis.js +17 -9
- package/dist/domain/webBundleAnalyzer.js +1 -1
- package/dist/domain/webCaptureDiff.js +5 -11
- package/dist/domain/webCaptureDiffSchemas.js +2 -1
- package/dist/domain/webMcpDiscovery.js +2 -1
- package/dist/dotnet/ManagedMemberInspectorCore.js +15 -7
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +57 -40
- package/dist/dotnet/ManagedMemberRows.js +2 -0
- package/dist/dotnet/ManagedMethodBodyReader.js +15 -8
- package/dist/dotnet/ManagedPeReader.js +2 -0
- package/dist/generatedMcpToolCatalog.js +1 -1
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +15 -5
- package/dist/ghidra/GhidraClient.js +38 -8
- package/dist/ghidra/GhidraFunctionValues.js +56 -20
- package/dist/ghidra/GhidraInstallation.js +7 -4
- package/dist/ghidra/GhidraInventoryValues.js +44 -9
- package/dist/ghidra/GhidraLauncher.js +18 -3
- package/dist/ghidra/GhidraProvider.js +23 -2
- package/dist/ghidra/GhidraRequestQueue.js +45 -4
- package/dist/ghidra/GhidraSessionValues.js +5 -0
- package/dist/hopper/HopperAnalysisProfile.js +2 -0
- package/dist/hopper/HopperProvider.js +29 -6
- package/dist/hopper/HopperTargetLease.js +18 -4
- package/dist/logger.js +0 -13
- package/dist/main/messages.js +0 -1
- package/dist/main/reload.js +3 -32
- package/dist/main/shutdown.js +1 -2
- package/dist/main/transport.js +0 -17
- package/dist/main.js +0 -10
- package/dist/native/AppleDispatchMetadata.js +582 -0
- package/dist/native/AppleObjcProtocols.js +88 -0
- package/dist/native/AppleSwiftVtables.js +86 -0
- package/dist/native/CommandRunner.js +1 -1
- package/dist/native/NativeHostCapabilities.js +23 -0
- package/dist/native/NativeMacOSProvider.js +61 -9
- package/dist/native/NativeMachoInspection.js +39 -6
- package/dist/native/NativeUiHelperRuntime.js +42 -0
- package/dist/native/NativeUiObservation.js +174 -0
- package/dist/native/parsers/codesign.js +4 -1
- package/dist/native/parsers/dyldInfo.js +51 -25
- package/dist/native/parsers/lipo.js +13 -4
- package/dist/native/parsers/otool.js +84 -39
- package/dist/native/parsers/plist.js +2 -1
- package/dist/process/ExecFileOutput.js +5 -1
- package/dist/process/ProcessOwnership.js +69 -33
- package/dist/process/ProcessOwnershipObservation.js +31 -12
- package/dist/process/ProviderProcess.js +4 -2
- package/dist/reference/ReferenceSourceReaderEntries.js +48 -31
- package/dist/reference/ReferenceSourceReaderErrors.js +24 -0
- package/dist/reference/ReferenceSourceReaderFile.js +11 -5
- package/dist/reference/ReferenceSourceReaderValidate.js +22 -8
- package/dist/server/createServer.js +7 -62
- package/dist/server/registerApplicationTools/helpers.js +2 -9
- package/dist/server/registerApplicationTools.js +0 -4
- package/dist/server/registerArtifactComparisonTool.js +1 -1
- package/dist/server/registerBrowserScenarioTool.js +4 -2
- package/dist/server/registerBrowserTools.js +7 -7
- package/dist/server/registerBundleComparisonTool.js +1 -1
- package/dist/server/registerCloseLifecycleTool.js +1 -1
- package/dist/server/registerElectronTools.js +10 -4
- package/dist/server/registerEnhancedTools.js +20 -12
- package/dist/server/registerEvidenceTools.js +4 -28
- package/dist/server/registerFunctionComparisonTool.js +1 -1
- package/dist/server/registerInvestigationTools.js +6 -6
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -2
- package/dist/server/registerManagedTools.js +28 -14
- package/dist/server/registerManagedWorkflowTools.js +0 -2
- package/dist/server/registerProcessComparisonTool.js +1 -3
- package/dist/server/registerSessionRecordTools.js +9 -9
- package/dist/server/registerSessionStatusTool.js +1 -1
- package/dist/server/registerSessionTools.js +28 -57
- package/dist/server/sessionAvailabilityPolicy.js +2 -3
- package/dist/server/sessionToolPolicies.js +0 -4
- package/dist/server/toolResult.js +8 -10
- package/package.json +32 -22
- package/skills/reverse-engineer-anything/SKILL.md +15 -11
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +3 -2
- package/skills/reverse-engineer-anything/references/javascript-applications.md +3 -2
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +8 -6
- package/skills/reverse-engineer-anything/references/runtime-observation.md +15 -11
- package/dist/application/CommandShimReplay.js +0 -152
- package/dist/application/ConfiguredRoots.js +0 -19
- package/dist/application/InstrumentedJavaScriptReplayHost.js +0 -36
- package/dist/application/JavaScriptReplayPermission.js +0 -16
- package/dist/application/JavaScriptReplayPlanning.js +0 -207
- package/dist/application/JavaScriptReplayService.js +0 -274
- package/dist/application/LoopbackReplay.js +0 -389
- package/dist/application/LoopbackReplayRecorder.js +0 -129
- package/dist/application/ManagedRuntimeCorrelationService.js +0 -104
- package/dist/application/NodeRuntimeCharacterizationService.js +0 -191
- package/dist/application/PermissionAuthority.js +0 -268
- package/dist/application/PermissionConfiguration.js +0 -26
- package/dist/application/PermissionFailure.js +0 -5
- package/dist/application/ProcessCaptureAuthority.js +0 -24
- package/dist/application/ProcessCapturePermission.js +0 -13
- package/dist/application/ProcessCheckpoints.js +0 -178
- package/dist/application/ProcessReactiveCoordinator.js +0 -223
- package/dist/application/ProcessReactiveEffects.js +0 -153
- package/dist/application/ProcessReactiveHarness.js +0 -106
- package/dist/application/ProcessReactiveObservations.js +0 -105
- package/dist/application/ProjectPermissionStore.js +0 -199
- package/dist/application/RuntimeExecutableDiagnostics.js +0 -198
- package/dist/application/Upgrade.js +0 -134
- package/dist/browser/SensitiveTextCapture.js +0 -8
- package/dist/cliPolicyCommands.js +0 -185
- package/dist/config/browserScenario.js +0 -77
- package/dist/config/electronAutomation.js +0 -35
- package/dist/config/javascriptReplay.js +0 -41
- package/dist/config/managedRuntime.js +0 -25
- package/dist/config/passiveObservation.js +0 -87
- package/dist/config/permissions.js +0 -23
- package/dist/config/processCapture.js +0 -47
- package/dist/contracts/replayMachineExample.js +0 -37
- package/dist/domain/javascriptExportInstrumentation.js +0 -95
- package/dist/domain/javascriptReplay.js +0 -360
- package/dist/domain/managedRuntimeCorrelation.js +0 -181
- package/dist/domain/nodeRuntimeCharacterization.js +0 -63
- package/dist/domain/permissionPolicy.js +0 -176
- package/dist/domain/processCaptureReactiveSchema.js +0 -68
- package/dist/domain/processCaptureReactiveValidation.js +0 -180
- package/dist/domain/processReactiveCheckpointDataflow.js +0 -32
- package/dist/domain/processReactiveMatching.js +0 -196
- package/dist/domain/processReactiveRuntime.js +0 -116
- package/dist/domain/processReactiveScenario.js +0 -296
- package/dist/domain/processReactiveScenarioPreflight.js +0 -95
- package/dist/domain/processReactiveTransition.js +0 -187
- package/dist/domain/replayMachine.js +0 -320
- package/dist/domain/replayMachineRun.js +0 -168
- package/dist/domain/replayMachineRuntime.js +0 -296
- package/dist/domain/replayMachineValues.js +0 -84
- package/dist/domain/runtimeCharacterization.js +0 -84
- package/dist/replay/JavaScriptReplayWorker.js +0 -382
- package/dist/replay/JavaScriptReplayWorkerTypes.js +0 -1
- package/dist/replay/LinuxJavaScriptReplayRunner.js +0 -216
- package/dist/replay/LinuxJavaScriptReplaySandbox.js +0 -121
- package/dist/replay/LinuxRuntimeClosure.js +0 -44
- package/dist/replay/LinuxSeccompPolicy.js +0 -40
- package/dist/replay/ReplayOutcome.js +0 -104
- package/dist/replay/ReplayProcessLifecycle.js +0 -96
- package/dist/replay/ReplaySeccompFile.js +0 -29
- package/dist/replay/ReplayWorkerProtocol.js +0 -58
- package/dist/replay/SystemJavaScriptReplayHost.js +0 -153
- package/dist/server/ProcessCaptureElicitation.js +0 -153
- package/dist/server/registerApplicationTools/characterization.js +0 -46
- package/dist/server/registerApplicationTools/controlledReplay.js +0 -31
- package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +0 -29
- package/dist/server/registerReplayMachineTool.js +0 -14
- package/skills/reverse-engineer-anything/references/controlled-replay.md +0 -12
|
@@ -4,6 +4,7 @@ import { CdpCaptureCompleteness } from "./CdpCaptureCompleteness.js";
|
|
|
4
4
|
import { authorizedMainFrame } from "./CdpAuthorizedMainFrame.js";
|
|
5
5
|
import { allowedSanitizedUrl, isHttpUrl, numberValue, recordValue, stringValue, } from "./CdpCaptureValues.js";
|
|
6
6
|
import { mainFrameUrl } from "./CdpCaptureDocuments.js";
|
|
7
|
+
import { isMainFrameNavigation } from "./CdpCaptureEventHelpers.js";
|
|
7
8
|
/** Observe external user actions without rejecting approved same-origin navigation. */
|
|
8
9
|
export const observeCdpSession = async (context) => {
|
|
9
10
|
const allowedOrigins = new Set(context.input.allowed_origins);
|
|
@@ -33,7 +34,7 @@ export const observeCdpSession = async (context) => {
|
|
|
33
34
|
phase: "browser_observation",
|
|
34
35
|
completed: 1,
|
|
35
36
|
total: 2,
|
|
36
|
-
message: "Browser observation armed; perform the
|
|
37
|
+
message: "Browser observation armed; perform the requested user action now",
|
|
37
38
|
});
|
|
38
39
|
let endReason = await waitForWindow(context.input.observation_ms, capture, context.signal);
|
|
39
40
|
if (endReason === "window_elapsed")
|
|
@@ -96,13 +97,13 @@ class TimelineCapture {
|
|
|
96
97
|
return;
|
|
97
98
|
switch (event.method) {
|
|
98
99
|
case "Page.frameRequestedNavigation":
|
|
99
|
-
this.#navigationRequested(params);
|
|
100
|
+
this.#navigationRequested(event, params);
|
|
100
101
|
break;
|
|
101
102
|
case "Page.frameNavigated":
|
|
102
|
-
this.#navigationCommitted(params);
|
|
103
|
+
this.#navigationCommitted(event, params);
|
|
103
104
|
break;
|
|
104
105
|
case "Page.navigatedWithinDocument":
|
|
105
|
-
this.#sameDocument(params);
|
|
106
|
+
this.#sameDocument(event, params);
|
|
106
107
|
break;
|
|
107
108
|
case "Network.requestWillBeSent":
|
|
108
109
|
this.#redirect(params);
|
|
@@ -150,8 +151,8 @@ class TimelineCapture {
|
|
|
150
151
|
const destination = scopedUrl(rawUrl, this.allowedOrigins);
|
|
151
152
|
this.finalUrl = destination.scope === "approved" ? destination.url : null;
|
|
152
153
|
}
|
|
153
|
-
#navigationRequested(params) {
|
|
154
|
-
if (
|
|
154
|
+
#navigationRequested(event, params) {
|
|
155
|
+
if (!isMainFrameNavigation(event, this.mainFrameId))
|
|
155
156
|
return;
|
|
156
157
|
const reason = safeDetail(params.reason);
|
|
157
158
|
this.#pendingReload = reason === "reload";
|
|
@@ -163,9 +164,9 @@ class TimelineCapture {
|
|
|
163
164
|
detail: reason,
|
|
164
165
|
});
|
|
165
166
|
}
|
|
166
|
-
#navigationCommitted(params) {
|
|
167
|
+
#navigationCommitted(event, params) {
|
|
167
168
|
const frame = recordValue(params.frame);
|
|
168
|
-
if (
|
|
169
|
+
if (!isMainFrameNavigation(event, this.mainFrameId))
|
|
169
170
|
return;
|
|
170
171
|
const rawUrl = stringValue(frame?.url);
|
|
171
172
|
const destination = scopedUrl(rawUrl, this.allowedOrigins);
|
|
@@ -185,8 +186,8 @@ class TimelineCapture {
|
|
|
185
186
|
this.end("target_left_scope");
|
|
186
187
|
}
|
|
187
188
|
}
|
|
188
|
-
#sameDocument(params) {
|
|
189
|
-
if (
|
|
189
|
+
#sameDocument(event, params) {
|
|
190
|
+
if (!isMainFrameNavigation(event, this.mainFrameId))
|
|
190
191
|
return;
|
|
191
192
|
const rawUrl = stringValue(params.url);
|
|
192
193
|
const destination = scopedUrl(rawUrl, this.allowedOrigins);
|
|
@@ -206,6 +207,9 @@ class TimelineCapture {
|
|
|
206
207
|
}
|
|
207
208
|
}
|
|
208
209
|
#redirect(params) {
|
|
210
|
+
const resourceType = stringValue(params.type);
|
|
211
|
+
if (resourceType !== undefined && resourceType !== "Document")
|
|
212
|
+
return;
|
|
209
213
|
if (stringValue(params.frameId) !== this.mainFrameId ||
|
|
210
214
|
recordValue(params.redirectResponse) === undefined)
|
|
211
215
|
return;
|
|
@@ -24,7 +24,7 @@ export const capturePage = async (context) => {
|
|
|
24
24
|
allowedOrigins,
|
|
25
25
|
limitations: [
|
|
26
26
|
"Observation starts when REA attaches; prior network and console activity is unavailable.",
|
|
27
|
-
"Raw network headers, bodies, cookies, storage values, console objects, and WebSocket payloads are never retained;
|
|
27
|
+
"Raw network headers, bodies, cookies, storage values, console objects, and WebSocket payloads are never retained; explicitly requested primitive console text is retained verbatim, while payload captures retain value-free shapes.",
|
|
28
28
|
"Source maps are reported only as declarative URLs and are not fetched.",
|
|
29
29
|
"URL-less scripts and console events without an allowed source URL are excluded because their origin cannot be proven.",
|
|
30
30
|
],
|
|
@@ -20,7 +20,7 @@ const buildScriptDraft = async (script, state) => {
|
|
|
20
20
|
let source = state
|
|
21
21
|
.context.input.include_script_sources
|
|
22
22
|
? await captureScriptSource(script, state)
|
|
23
|
-
: sourceExcluded("source capture was not
|
|
23
|
+
: sourceExcluded("source capture was not selected");
|
|
24
24
|
const inventoryScript = {
|
|
25
25
|
frame_id: state.events.frameForScript(script, state.frameIds),
|
|
26
26
|
url: script.url,
|
|
@@ -148,14 +148,15 @@ const linkParameters = (value) => {
|
|
|
148
148
|
const safeDestination = (value, baseUrl, allowedOrigins) => {
|
|
149
149
|
try {
|
|
150
150
|
const parsed = new URL(value, baseUrl);
|
|
151
|
+
const sanitized = sanitizeBrowserUrl(parsed.href).url;
|
|
151
152
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:")
|
|
152
|
-
return { url:
|
|
153
|
+
return { url: sanitized, scope: "unsupported" };
|
|
153
154
|
if (!allowedOrigins.has(parsed.origin))
|
|
154
|
-
return { url:
|
|
155
|
-
return { url:
|
|
155
|
+
return { url: sanitized, scope: "outside_policy" };
|
|
156
|
+
return { url: sanitized, scope: "approved" };
|
|
156
157
|
}
|
|
157
158
|
catch {
|
|
158
|
-
return { url:
|
|
159
|
+
return { url: value, scope: "unsupported" };
|
|
159
160
|
}
|
|
160
161
|
};
|
|
161
162
|
const permissionFeatures = (value) => [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createWebScreenshotArtifact } from "../domain/webScreenshot.js";
|
|
2
2
|
import { BrowserObservationError } from "../domain/errors.js";
|
|
3
|
+
import { isMainFrameNavigation } from "./CdpCaptureEventHelpers.js";
|
|
3
4
|
import { allowedSanitizedUrl, recordValue, stringValue, } from "./CdpCaptureValues.js";
|
|
4
5
|
import { mainFrameUrl } from "./CdpCaptureDocuments.js";
|
|
5
6
|
import { captureFrames } from "./CdpCaptureDocuments.js";
|
|
@@ -21,7 +22,13 @@ export const captureCdpScreenshot = async (context) => {
|
|
|
21
22
|
const mainFrame = captureFrames(before, origins, 1).items[0];
|
|
22
23
|
if (authorized === undefined || mainFrame === undefined)
|
|
23
24
|
throw new BrowserObservationError("inspect_web_page", "target_not_allowed");
|
|
24
|
-
const
|
|
25
|
+
const initialFrame = recordValue(recordValue(recordValue(before)?.frameTree)?.frame);
|
|
26
|
+
const navigation = {
|
|
27
|
+
changed: false,
|
|
28
|
+
leftScope: false,
|
|
29
|
+
url: beforeUrl,
|
|
30
|
+
loaderId: stringValue(initialFrame?.loaderId),
|
|
31
|
+
};
|
|
25
32
|
const removeListener = context.connection.onEvent((event) => {
|
|
26
33
|
if (event.sessionId !== context.sessionId)
|
|
27
34
|
return;
|
|
@@ -67,19 +74,23 @@ export const captureCdpScreenshot = async (context) => {
|
|
|
67
74
|
artifact: createWebScreenshotArtifact(bytes),
|
|
68
75
|
completeness: new CdpCaptureCompleteness().snapshot(),
|
|
69
76
|
limitations: [
|
|
70
|
-
"The screenshot contains the visible viewport
|
|
77
|
+
"The screenshot contains the visible viewport, including on-screen content.",
|
|
71
78
|
"REA does not scroll, evaluate JavaScript, or capture beyond the current viewport.",
|
|
72
79
|
],
|
|
73
80
|
};
|
|
74
81
|
};
|
|
75
82
|
const observeScreenshotNavigation = (event, mainFrameId, origins, state) => {
|
|
83
|
+
if (!isMainFrameNavigation(event, mainFrameId))
|
|
84
|
+
return;
|
|
76
85
|
const params = recordValue(event.params);
|
|
77
86
|
if (params === undefined)
|
|
78
87
|
return;
|
|
79
88
|
const frame = event.method === "Page.frameNavigated" ? recordValue(params.frame) : params;
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
-
|
|
89
|
+
if (event.method === "Page.frameNavigated" &&
|
|
90
|
+
state.loaderId !== undefined &&
|
|
91
|
+
state.loaderId !== "" &&
|
|
92
|
+
stringValue(frame?.loaderId) === state.loaderId &&
|
|
93
|
+
stringValue(frame?.url) === state.url)
|
|
83
94
|
return;
|
|
84
95
|
state.changed = true;
|
|
85
96
|
if (allowedSanitizedUrl(frame?.url, origins) === undefined)
|
|
@@ -17,24 +17,45 @@ export const openCdpTargetSession = async (discovery, target, operation, signal)
|
|
|
17
17
|
}
|
|
18
18
|
};
|
|
19
19
|
/** Disable enabled domains, detach browser sessions, and close REA's socket. */
|
|
20
|
-
export const closeCdpTargetSession = async (targetSession, enabledDomains) => {
|
|
20
|
+
export const closeCdpTargetSession = async (targetSession, enabledDomains, signal) => {
|
|
21
21
|
const { connection, sessionId } = targetSession;
|
|
22
|
-
for (const domain of enabledDomains)
|
|
22
|
+
for (const [index, domain] of enabledDomains.entries()) {
|
|
23
|
+
if (signal?.aborted === true) {
|
|
24
|
+
await closeCancelledTargetSession(targetSession, enabledDomains.slice(index));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
23
27
|
try {
|
|
24
|
-
await connection.send(`${domain}.disable`, {}, sessionId);
|
|
28
|
+
await connection.send(`${domain}.disable`, {}, sessionId, signal);
|
|
25
29
|
}
|
|
26
30
|
catch {
|
|
27
31
|
// Cleanup continues to the detach or direct-socket close boundary.
|
|
28
32
|
}
|
|
33
|
+
}
|
|
34
|
+
if (signal?.aborted === true) {
|
|
35
|
+
await closeCancelledTargetSession(targetSession, []);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
29
38
|
if (sessionId !== undefined)
|
|
30
39
|
try {
|
|
31
|
-
await connection.send("Target.detachFromTarget", { sessionId });
|
|
40
|
+
await connection.send("Target.detachFromTarget", { sessionId }, undefined, signal);
|
|
32
41
|
}
|
|
33
42
|
catch {
|
|
34
43
|
// Closing REA's socket is the final non-destructive cleanup boundary.
|
|
35
44
|
}
|
|
36
45
|
await connection.close();
|
|
37
46
|
};
|
|
47
|
+
const closeCancelledTargetSession = async ({ connection, sessionId }, enabledDomains) => {
|
|
48
|
+
const commands = enabledDomains.map((domain) => connection.send(`${domain}.disable`, {}, sessionId));
|
|
49
|
+
if (sessionId !== undefined)
|
|
50
|
+
commands.push(connection.send("Target.detachFromTarget", { sessionId }));
|
|
51
|
+
const settled = Promise.allSettled(commands);
|
|
52
|
+
try {
|
|
53
|
+
await connection.close();
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
await settled;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
38
59
|
const attachedSessionId = (value, operation) => {
|
|
39
60
|
if (typeof value !== "object" ||
|
|
40
61
|
value === null ||
|
|
@@ -3,9 +3,8 @@ import { inferJsonShape } from "../domain/jsonShape.js";
|
|
|
3
3
|
import { CdpCaptureCompleteness } from "./CdpCaptureCompleteness.js";
|
|
4
4
|
import { BrowserObservationError } from "../domain/errors.js";
|
|
5
5
|
import { allowedSanitizedUrl, delayWithCancellation, numberValue, recordValue, recordsValue, stringValue, } from "./CdpCaptureValues.js";
|
|
6
|
-
import { captureFrames, mainFrameUrl } from "./CdpCaptureDocuments.js";
|
|
6
|
+
import { captureFrames, mainFrameUrl, walkFrameTrees, } from "./CdpCaptureDocuments.js";
|
|
7
7
|
import { optionalCdpCommand } from "./CdpOptionalCommand.js";
|
|
8
|
-
import { redactSensitiveText } from "./SensitiveTextCapture.js";
|
|
9
8
|
/** Discover WebMCP registrations without evaluating or invoking page code. */
|
|
10
9
|
export const discoverWebMcp = async (context) => {
|
|
11
10
|
const origins = new Set(context.input.allowed_origins);
|
|
@@ -20,16 +19,16 @@ export const discoverWebMcp = async (context) => {
|
|
|
20
19
|
if (allowedSanitizedUrl(initialUrl, origins) === undefined)
|
|
21
20
|
throw new BrowserObservationError("inspect_web_page", "target_not_allowed");
|
|
22
21
|
const frames = captureFrames(frameTree, origins, undefined, completeness).items;
|
|
23
|
-
const frameUrls =
|
|
24
|
-
frame.frame_id,
|
|
25
|
-
{
|
|
26
|
-
url: frame.url,
|
|
27
|
-
origin: frame.origin,
|
|
28
|
-
parentFrameId: frame.parent_frame_id,
|
|
29
|
-
},
|
|
30
|
-
]));
|
|
22
|
+
const frameUrls = initialFrameScope(frameTree, frames, completeness);
|
|
31
23
|
const tools = new Map();
|
|
32
|
-
const frameScope = {
|
|
24
|
+
const frameScope = {
|
|
25
|
+
origins,
|
|
26
|
+
frames: frameUrls,
|
|
27
|
+
tools,
|
|
28
|
+
completeness,
|
|
29
|
+
transientFrames: new Set(),
|
|
30
|
+
resolvedTransientFrames: new Set(),
|
|
31
|
+
};
|
|
33
32
|
const removeListener = context.connection.onEvent((event) => {
|
|
34
33
|
if (event.sessionId !== context.sessionId)
|
|
35
34
|
return;
|
|
@@ -41,6 +40,8 @@ export const discoverWebMcp = async (context) => {
|
|
|
41
40
|
frames: frameUrls,
|
|
42
41
|
tools,
|
|
43
42
|
completeness,
|
|
43
|
+
transientFrames: frameScope.transientFrames,
|
|
44
|
+
resolvedTransientFrames: frameScope.resolvedTransientFrames,
|
|
44
45
|
});
|
|
45
46
|
});
|
|
46
47
|
await context.progress?.report({
|
|
@@ -59,6 +60,8 @@ export const discoverWebMcp = async (context) => {
|
|
|
59
60
|
// CDP sends the enable response before the required toolsAdded replay.
|
|
60
61
|
await delayWithCancellation(context.input.observation_ms, "discover_webmcp_tools", context.signal);
|
|
61
62
|
await assertStableAuthorizedFrame(context, initialUrl, origins);
|
|
63
|
+
if (frameScope.transientFrames.size > 0)
|
|
64
|
+
completeness.attachLimited("webmcp_tools");
|
|
62
65
|
return buildWebMcpResult({
|
|
63
66
|
context,
|
|
64
67
|
frameTree,
|
|
@@ -79,6 +82,27 @@ export const discoverWebMcp = async (context) => {
|
|
|
79
82
|
});
|
|
80
83
|
}
|
|
81
84
|
};
|
|
85
|
+
const initialFrameScope = (frameTree, frames, completeness) => {
|
|
86
|
+
const scoped = new Map(frames.map((frame) => [
|
|
87
|
+
frame.frame_id,
|
|
88
|
+
{
|
|
89
|
+
url: frame.url,
|
|
90
|
+
origin: frame.origin,
|
|
91
|
+
parentFrameId: frame.parent_frame_id,
|
|
92
|
+
},
|
|
93
|
+
]));
|
|
94
|
+
const root = recordValue(recordValue(frameTree)?.frameTree);
|
|
95
|
+
if (root === undefined)
|
|
96
|
+
return scoped;
|
|
97
|
+
for (const tree of walkFrameTrees(root, () => completeness.exclude("webmcp_tools", "invalid_protocol_value"))) {
|
|
98
|
+
const frame = recordValue(tree.frame);
|
|
99
|
+
const frameId = stringValue(frame?.id);
|
|
100
|
+
const prior = frameId === undefined ? undefined : scoped.get(frameId);
|
|
101
|
+
if (frameId !== undefined && prior !== undefined)
|
|
102
|
+
scoped.set(frameId, { ...prior, loaderId: stringValue(frame?.loaderId) });
|
|
103
|
+
}
|
|
104
|
+
return scoped;
|
|
105
|
+
};
|
|
82
106
|
const ingestFrameScopeEvent = (event, state) => {
|
|
83
107
|
const params = recordValue(event.params);
|
|
84
108
|
if (params === undefined)
|
|
@@ -87,9 +111,9 @@ const ingestFrameScopeEvent = (event, state) => {
|
|
|
87
111
|
case "Page.frameDetached":
|
|
88
112
|
return handleFrameDetached(params, state);
|
|
89
113
|
case "Page.frameNavigated":
|
|
90
|
-
return handleFrameUpdate(recordValue(params.frame), state);
|
|
114
|
+
return handleFrameUpdate(recordValue(params.frame), state, true);
|
|
91
115
|
case "Page.navigatedWithinDocument":
|
|
92
|
-
return handleFrameUpdate(params, state);
|
|
116
|
+
return handleFrameUpdate(params, state, false);
|
|
93
117
|
default:
|
|
94
118
|
return false;
|
|
95
119
|
}
|
|
@@ -101,30 +125,72 @@ const handleFrameDetached = (params, state) => {
|
|
|
101
125
|
return true;
|
|
102
126
|
}
|
|
103
127
|
removeFrame(frameId, state.frames, state.tools);
|
|
128
|
+
state.transientFrames.delete(frameId);
|
|
129
|
+
state.resolvedTransientFrames.delete(frameId);
|
|
104
130
|
return true;
|
|
105
131
|
};
|
|
106
|
-
const handleFrameUpdate = (frame, state) => {
|
|
132
|
+
const handleFrameUpdate = (frame, state, documentCommitted) => {
|
|
133
|
+
if (frame === undefined) {
|
|
134
|
+
state.completeness.exclude("webmcp_tools", "invalid_protocol_value");
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
107
137
|
const frameId = stringValue(frame?.id) ?? stringValue(frame?.frameId);
|
|
108
138
|
if (frameId === undefined) {
|
|
109
139
|
state.completeness.exclude("webmcp_tools", "invalid_protocol_value");
|
|
110
140
|
return true;
|
|
111
141
|
}
|
|
142
|
+
const rawUrl = stringValue(frame?.url);
|
|
143
|
+
// Chromium can briefly commit an inherited, empty document while replacing
|
|
144
|
+
// a subframe. That intermediate URL says nothing about the frame's eventual
|
|
145
|
+
// scope or its registered tools; wait for the next committed URL (or the
|
|
146
|
+
// authoritative frame-tree re-probe at the end of discovery).
|
|
147
|
+
if (isTransientFrameUrl(rawUrl)) {
|
|
148
|
+
if (documentCommitted) {
|
|
149
|
+
removeFrameTools(frameId, state.tools);
|
|
150
|
+
state.transientFrames.add(frameId);
|
|
151
|
+
state.resolvedTransientFrames.delete(frameId);
|
|
152
|
+
}
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
updateFrameScope(frame, frameId, state, documentCommitted);
|
|
156
|
+
return true;
|
|
157
|
+
};
|
|
158
|
+
const updateFrameScope = (frame, frameId, state, documentCommitted) => {
|
|
112
159
|
const url = allowedSanitizedUrl(frame?.url, state.origins);
|
|
113
160
|
if (url === undefined || url.origin === null) {
|
|
114
|
-
|
|
161
|
+
removeFrameTools(frameId, state.tools);
|
|
162
|
+
state.frames.delete(frameId);
|
|
115
163
|
state.completeness.exclude("webmcp_tools", "out_of_target_scope");
|
|
116
|
-
return
|
|
164
|
+
return;
|
|
117
165
|
}
|
|
166
|
+
const previous = state.frames.get(frameId);
|
|
167
|
+
const loaderId = stringValue(frame?.loaderId);
|
|
168
|
+
if (hasNewDocument(documentCommitted, previous, url.url, loaderId))
|
|
169
|
+
removeFrameTools(frameId, state.tools);
|
|
170
|
+
if (documentCommitted && state.transientFrames.has(frameId))
|
|
171
|
+
state.resolvedTransientFrames.add(frameId);
|
|
118
172
|
state.frames.set(frameId, {
|
|
119
173
|
url: url.url,
|
|
120
174
|
origin: url.origin,
|
|
175
|
+
...(loaderId === undefined ? {} : { loaderId }),
|
|
121
176
|
parentFrameId: (stringValue(frame?.parentId) ??
|
|
122
177
|
state.frames.get(frameId)?.parentFrameId ??
|
|
123
178
|
"") ||
|
|
124
179
|
null,
|
|
125
180
|
});
|
|
126
|
-
return true;
|
|
127
181
|
};
|
|
182
|
+
const hasNewDocument = (documentCommitted, previous, url, loaderId) => documentCommitted &&
|
|
183
|
+
previous !== undefined &&
|
|
184
|
+
(previous.url !== url ||
|
|
185
|
+
(loaderId !== undefined &&
|
|
186
|
+
previous.loaderId !== undefined &&
|
|
187
|
+
previous.loaderId !== loaderId));
|
|
188
|
+
const removeFrameTools = (frameId, tools) => {
|
|
189
|
+
for (const [key, tool] of tools)
|
|
190
|
+
if (tool.frame_id === frameId)
|
|
191
|
+
tools.delete(key);
|
|
192
|
+
};
|
|
193
|
+
const isTransientFrameUrl = (url) => url === "" || url === "about:blank" || url === "about:srcdoc";
|
|
128
194
|
const removeFrame = (frameId, frames, tools) => {
|
|
129
195
|
const pending = [frameId];
|
|
130
196
|
const removed = new Set();
|
|
@@ -151,7 +217,7 @@ const assertStableAuthorizedFrame = async (context, initialUrl, origins) => {
|
|
|
151
217
|
throw new BrowserObservationError("inspect_web_page", "target_changed");
|
|
152
218
|
};
|
|
153
219
|
const ingestWebMcpEvent = (options) => {
|
|
154
|
-
const { event, input, frames, tools, completeness } = options;
|
|
220
|
+
const { event, input, frames, tools, completeness, transientFrames, resolvedTransientFrames, } = options;
|
|
155
221
|
const params = recordValue(event.params);
|
|
156
222
|
if (params === undefined)
|
|
157
223
|
return;
|
|
@@ -170,6 +236,13 @@ const ingestWebMcpEvent = (options) => {
|
|
|
170
236
|
if (event.method !== "WebMCP.toolsAdded")
|
|
171
237
|
return;
|
|
172
238
|
for (const declared of recordsValue(params.tools)) {
|
|
239
|
+
const frameId = stringValue(declared.frameId);
|
|
240
|
+
if (frameId !== undefined && transientFrames.has(frameId)) {
|
|
241
|
+
if (!resolvedTransientFrames.has(frameId))
|
|
242
|
+
continue;
|
|
243
|
+
transientFrames.delete(frameId);
|
|
244
|
+
resolvedTransientFrames.delete(frameId);
|
|
245
|
+
}
|
|
173
246
|
const normalized = normalizeTool(declared, input, frames, completeness);
|
|
174
247
|
if (normalized === undefined)
|
|
175
248
|
continue;
|
|
@@ -187,11 +260,11 @@ const normalizeTool = (value, input, frames, completeness) => {
|
|
|
187
260
|
completeness.exclude("webmcp_tools", "out_of_target_scope");
|
|
188
261
|
return undefined;
|
|
189
262
|
}
|
|
190
|
-
const description =
|
|
263
|
+
const description = stringValue(value.description) ?? "";
|
|
191
264
|
const annotations = recordValue(value.annotations);
|
|
192
265
|
return {
|
|
193
266
|
tool_key: toolKey(frame.url, name),
|
|
194
|
-
name
|
|
267
|
+
name,
|
|
195
268
|
description,
|
|
196
269
|
frame_id: frameId,
|
|
197
270
|
frame_url: frame.url,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { pathToFileURL } from "node:url";
|
|
1
2
|
import { browserOriginSchema, sanitizeBrowserUrl, } from "../domain/browserObservation.js";
|
|
2
3
|
import { authorizedElectronFile } from "./ElectronFileScope.js";
|
|
3
4
|
/** Resolve a protocol location exposed by the explicitly selected Inspector endpoint. */
|
|
@@ -34,5 +35,30 @@ export const authorizeRuntimeLocation = async (value) => {
|
|
|
34
35
|
},
|
|
35
36
|
};
|
|
36
37
|
};
|
|
37
|
-
/**
|
|
38
|
-
export const authorizeRuntimeTargetLocation = async (value) =>
|
|
38
|
+
/** Interpret Node's lossy discovery metadata separately from scriptParsed URLs. */
|
|
39
|
+
export const authorizeRuntimeTargetLocation = async (value, context) => {
|
|
40
|
+
if (context.type !== "node" ||
|
|
41
|
+
!/^node\.js\/v/iu.test(context.product) ||
|
|
42
|
+
!value.startsWith("file://"))
|
|
43
|
+
return authorizeRuntimeLocation(value);
|
|
44
|
+
const reportedPath = value.slice("file://".length);
|
|
45
|
+
if (!reportedPath.startsWith("/") && !/^[a-z]:[/\\_]/iu.test(reportedPath))
|
|
46
|
+
return authorizeRuntimeLocation(value);
|
|
47
|
+
// Node concatenates the pathname, then replaces quotes and backslashes with
|
|
48
|
+
// underscores. A remaining underscore cannot prove which pathname was used.
|
|
49
|
+
if (process.platform !== "win32" && !/[_"\\]/u.test(reportedPath)) {
|
|
50
|
+
if (reportedPath.startsWith("/")) {
|
|
51
|
+
const decision = await authorizeRuntimeLocation(pathToFileURL(reportedPath).href);
|
|
52
|
+
if (decision.allowed)
|
|
53
|
+
return decision;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
allowed: true,
|
|
58
|
+
location: {
|
|
59
|
+
kind: "unresolved",
|
|
60
|
+
reported_url: value,
|
|
61
|
+
reason: "unverifiable-file-location",
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { sanitizeBrowserUrl } from "../domain/browserObservation.js";
|
|
2
1
|
import { browserScenarioCaptureSchema, classifyBrowserScenarioCompleteness, browserScenarioStepSchema, browserStepArtifactsSchema, } from "../domain/browserScenarioCapture.js";
|
|
3
2
|
import { AnalysisError, BrowserObservationError, ProviderAdapterError, } from "../domain/errors.js";
|
|
4
3
|
import { err, ok } from "../domain/result.js";
|
|
@@ -53,8 +52,8 @@ const createStep = (input) => browserScenarioStepSchema.parse({
|
|
|
53
52
|
action: input.action,
|
|
54
53
|
status: input.status,
|
|
55
54
|
elapsed_ms: input.elapsedMs,
|
|
56
|
-
before_url:
|
|
57
|
-
after_url:
|
|
55
|
+
before_url: input.beforeUrl,
|
|
56
|
+
after_url: input.afterUrl,
|
|
58
57
|
error: input.error,
|
|
59
58
|
event_sequence_start: input.eventStart,
|
|
60
59
|
event_sequence_end: input.eventEnd,
|
|
@@ -70,8 +69,8 @@ const initialStep = async (input) => {
|
|
|
70
69
|
action: "goto_start",
|
|
71
70
|
status: "completed",
|
|
72
71
|
elapsedMs,
|
|
73
|
-
beforeUrl: session.initialUrl,
|
|
74
|
-
afterUrl: session.currentUrl(),
|
|
72
|
+
beforeUrl: session.sanitizeUrl(session.initialUrl),
|
|
73
|
+
afterUrl: session.sanitizeUrl(session.currentUrl()),
|
|
75
74
|
error: null,
|
|
76
75
|
eventStart: 1,
|
|
77
76
|
eventEnd: session.lastEventSequence(),
|
|
@@ -80,7 +79,7 @@ const initialStep = async (input) => {
|
|
|
80
79
|
};
|
|
81
80
|
const executeStep = async (input) => {
|
|
82
81
|
const { session, scenario, action, stepIndex, priorFailure, signal } = input;
|
|
83
|
-
const beforeUrl = session.currentUrl();
|
|
82
|
+
const beforeUrl = session.sanitizeUrl(session.currentUrl());
|
|
84
83
|
const eventStart = session.nextEventSequence();
|
|
85
84
|
const requested = requestedForStep(scenario, stepIndex);
|
|
86
85
|
if (priorFailure)
|
|
@@ -128,7 +127,7 @@ const executeStep = async (input) => {
|
|
|
128
127
|
...outcome,
|
|
129
128
|
elapsedMs: Date.now() - actionStartedAt,
|
|
130
129
|
beforeUrl,
|
|
131
|
-
afterUrl: session.currentUrl(),
|
|
130
|
+
afterUrl: session.sanitizeUrl(session.currentUrl()),
|
|
132
131
|
eventStart,
|
|
133
132
|
eventEnd: session.lastEventSequence(),
|
|
134
133
|
artifacts,
|
|
@@ -139,6 +138,8 @@ const globalCompleteness = (scenario, session, steps) => {
|
|
|
139
138
|
const truncated = steps.flatMap(({ completeness }) => completeness.truncated_sections);
|
|
140
139
|
if (session.mode === "connect")
|
|
141
140
|
missing.push("events");
|
|
141
|
+
if ((session.eventLimitations?.().length ?? 0) > 0)
|
|
142
|
+
missing.push("events");
|
|
142
143
|
return classifyBrowserScenarioCompleteness(missing, truncated);
|
|
143
144
|
};
|
|
144
145
|
const runScenario = async (factory, scenario, options) => {
|
|
@@ -184,7 +185,6 @@ const runScenario = async (factory, scenario, options) => {
|
|
|
184
185
|
},
|
|
185
186
|
scenario: {
|
|
186
187
|
start_origin: new URL(scenario.start_url.url).origin,
|
|
187
|
-
allowed_origins: scenario.allowed_origins,
|
|
188
188
|
action_count: scenario.actions.length,
|
|
189
189
|
secret_references: scenario.secrets.map(({ secret_id: id }) => id).sort(),
|
|
190
190
|
},
|
|
@@ -196,6 +196,7 @@ const runScenario = async (factory, scenario, options) => {
|
|
|
196
196
|
"Event sequence records provider receipt order; simultaneous browser causality is not inferred.",
|
|
197
197
|
"Response bodies are not retained.",
|
|
198
198
|
"Storage values are hashed only after declared-secret redaction.",
|
|
199
|
+
...(session.eventLimitations?.() ?? []),
|
|
199
200
|
...(session.mode === "connect"
|
|
200
201
|
? [
|
|
201
202
|
"CDP attachment cannot recover pre-attach events or guarantee launch-time context options.",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { BrowserObservationError } from "../domain/errors.js";
|
|
3
|
-
import { redactSensitiveText } from "./SensitiveTextCapture.js";
|
|
4
3
|
const OPERATION = "capture_electron_scenario";
|
|
5
4
|
const hookEventSchema = z.strictObject({
|
|
6
5
|
sequence: z.number().int().min(1),
|
|
@@ -123,7 +122,7 @@ export const runElectronActions = async (application, input, options) => {
|
|
|
123
122
|
target: selectedWindow === undefined ? null : `window:${String(windowIndex)}`,
|
|
124
123
|
status: options.signal?.aborted ? "cancelled" : "failed",
|
|
125
124
|
elapsed_ms: Date.now() - actionStartedAt,
|
|
126
|
-
error: safeActionErrorMessage(cause
|
|
125
|
+
error: safeActionErrorMessage(cause),
|
|
127
126
|
});
|
|
128
127
|
break;
|
|
129
128
|
}
|
|
@@ -298,12 +297,6 @@ export const runWithExecutionLimits = async (operation, signal, deadline) => {
|
|
|
298
297
|
signal?.removeEventListener("abort", abortListener);
|
|
299
298
|
}
|
|
300
299
|
};
|
|
301
|
-
const safeActionErrorMessage = (cause
|
|
302
|
-
|
|
303
|
-
const inputValues = Object.values(action)
|
|
304
|
-
.filter((value) => typeof value === "string" && value.length > 0)
|
|
305
|
-
.sort((left, right) => right.length - left.length);
|
|
306
|
-
for (const value of inputValues)
|
|
307
|
-
message = message.split(value).join("<redacted-input>");
|
|
308
|
-
return redactSensitiveText(message);
|
|
300
|
+
const safeActionErrorMessage = (cause) => {
|
|
301
|
+
return cause instanceof Error ? cause.message : "Electron action failed";
|
|
309
302
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { realpath } from "node:fs/promises";
|
|
2
|
+
import { dirname } from "node:path";
|
|
2
3
|
import { randomUUID } from "node:crypto";
|
|
3
4
|
import { fileURLToPath } from "node:url";
|
|
4
5
|
import { _electron as electron } from "playwright-core";
|
|
5
6
|
import { electronActiveObservationResultSchema, } from "../domain/electronActiveObservation.js";
|
|
6
7
|
import { AnalysisError, BrowserObservationError, ProviderAdapterError, } from "../domain/errors.js";
|
|
7
|
-
import { isPathContained } from "../domain/permissionPolicy.js";
|
|
8
8
|
import { err, ok } from "../domain/result.js";
|
|
9
9
|
import { cleanupOwnedProcessGroup, cleanupWindowsProcessTree, observeOwnedProcessLineage, selectCapturedProcessGroupIds, verifyNoTokenOwnedProcesses, } from "../process/ProcessOwnership.js";
|
|
10
10
|
import { runElectronActions, readApplicationState, runWithExecutionLimits, } from "./PlaywrightElectronActiveActions.js";
|
|
@@ -243,13 +243,13 @@ const createResult = (paths, input, actions, state) => {
|
|
|
243
243
|
});
|
|
244
244
|
};
|
|
245
245
|
const canonicalPaths = async (input) => {
|
|
246
|
-
const [executable, application
|
|
246
|
+
const [executable, application] = await Promise.all([
|
|
247
247
|
realpath(input.executable_path),
|
|
248
248
|
realpath(input.application_path),
|
|
249
|
-
realpath(input.application_root),
|
|
250
249
|
]);
|
|
251
|
-
|
|
252
|
-
|
|
250
|
+
const root = input.application_root === undefined
|
|
251
|
+
? dirname(application)
|
|
252
|
+
: await realpath(input.application_root);
|
|
253
253
|
return { executable, application, root };
|
|
254
254
|
};
|
|
255
255
|
const safeElectronEnvironment = (runId) => Object.fromEntries([
|