rea-agents 3.2.1 → 4.0.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 +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
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { createReadStream } from "node:fs";
|
|
2
|
+
import { stat } from "node:fs/promises";
|
|
3
|
+
import { Readable } from "node:stream";
|
|
2
4
|
import { XcrunCommandRunner, } from "../native/CommandRunner.js";
|
|
3
5
|
import { parseLipoArchitectures } from "../native/parsers/lipo.js";
|
|
4
6
|
import { ArtifactReaderFailure, } from "./ArtifactReader.js";
|
|
7
|
+
import { streamChunkToBuffer } from "./StreamBytes.js";
|
|
5
8
|
/** Read-only universal Mach-O slice reader backed by native lipo metadata. */
|
|
6
9
|
export class MachOSliceArtifactReader {
|
|
7
10
|
path;
|
|
@@ -24,9 +27,17 @@ export class MachOSliceArtifactReader {
|
|
|
24
27
|
exit_code: captured.value.exitCode,
|
|
25
28
|
effects: ["read"],
|
|
26
29
|
};
|
|
30
|
+
const fileSize = (await stat(this.path)).size;
|
|
27
31
|
for (const architecture of parseLipoArchitectures(captured.value.stdout)) {
|
|
28
32
|
if (architecture.file_offset === null || architecture.size === null)
|
|
29
33
|
throw new ArtifactReaderFailure("integrity", "lipo omitted a universal slice byte range");
|
|
34
|
+
if (!Number.isSafeInteger(architecture.file_offset) ||
|
|
35
|
+
!Number.isSafeInteger(architecture.size) ||
|
|
36
|
+
architecture.file_offset < 0 ||
|
|
37
|
+
architecture.size <= 0 ||
|
|
38
|
+
!Number.isSafeInteger(architecture.file_offset + architecture.size) ||
|
|
39
|
+
architecture.file_offset + architecture.size > fileSize)
|
|
40
|
+
throw new ArtifactReaderFailure("integrity", `lipo reported an out-of-bounds Mach-O slice: ${architecture.name}`);
|
|
30
41
|
yield {
|
|
31
42
|
path: `slices/${architecture.name}`,
|
|
32
43
|
kind: "slice",
|
|
@@ -42,17 +53,48 @@ export class MachOSliceArtifactReader {
|
|
|
42
53
|
};
|
|
43
54
|
}
|
|
44
55
|
}
|
|
45
|
-
open(entry, signal) {
|
|
56
|
+
async open(entry, signal) {
|
|
46
57
|
if (signal?.aborted === true)
|
|
47
58
|
return Promise.reject(new ArtifactReaderFailure("cancelled", "Mach-O slice read cancelled"));
|
|
48
59
|
const [offsetText, sizeText] = entry.adapterKey.split(":");
|
|
49
|
-
const offset =
|
|
50
|
-
const size =
|
|
60
|
+
const offset = parseSliceKeyInteger(offsetText);
|
|
61
|
+
const size = parseSliceKeyInteger(sizeText);
|
|
51
62
|
if (!Number.isSafeInteger(offset) ||
|
|
52
63
|
!Number.isSafeInteger(size) ||
|
|
64
|
+
offset === null ||
|
|
65
|
+
size === null ||
|
|
66
|
+
offset < 0 ||
|
|
53
67
|
size <= 0)
|
|
54
|
-
|
|
55
|
-
|
|
68
|
+
throw new ArtifactReaderFailure("integrity", "Invalid Mach-O slice byte range");
|
|
69
|
+
const fileSize = (await stat(this.path)).size;
|
|
70
|
+
if (!Number.isSafeInteger(offset + size) || offset + size > fileSize)
|
|
71
|
+
throw new ArtifactReaderFailure("integrity", `Mach-O slice range is outside the artifact: ${entry.path}`);
|
|
72
|
+
const source = createReadStream(this.path, {
|
|
73
|
+
start: offset,
|
|
74
|
+
end: offset + size - 1,
|
|
75
|
+
...(signal === undefined ? {} : { signal }),
|
|
76
|
+
});
|
|
77
|
+
return Readable.from((async function* () {
|
|
78
|
+
let observedBytes = 0;
|
|
79
|
+
try {
|
|
80
|
+
for await (const raw of source) {
|
|
81
|
+
const chunk = streamChunkToBuffer(raw);
|
|
82
|
+
observedBytes += chunk.byteLength;
|
|
83
|
+
if (observedBytes > size)
|
|
84
|
+
throw new ArtifactReaderFailure("integrity", `Mach-O slice exceeded its reported size: ${entry.path}`);
|
|
85
|
+
yield chunk;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (cause) {
|
|
89
|
+
if (cause instanceof ArtifactReaderFailure)
|
|
90
|
+
throw cause;
|
|
91
|
+
if (signal?.aborted === true)
|
|
92
|
+
throw new ArtifactReaderFailure("cancelled", "Mach-O slice read cancelled", { cause });
|
|
93
|
+
throw new ArtifactReaderFailure("integrity", `Could not read Mach-O slice range: ${entry.path}`, { cause });
|
|
94
|
+
}
|
|
95
|
+
if (observedBytes !== size)
|
|
96
|
+
throw new ArtifactReaderFailure("integrity", `Mach-O slice size disagrees with lipo metadata: ${entry.path}`);
|
|
97
|
+
})());
|
|
56
98
|
}
|
|
57
99
|
provenance() {
|
|
58
100
|
return this.#command === undefined ? [] : [structuredClone(this.#command)];
|
|
@@ -61,3 +103,9 @@ export class MachOSliceArtifactReader {
|
|
|
61
103
|
return Promise.resolve();
|
|
62
104
|
}
|
|
63
105
|
}
|
|
106
|
+
const parseSliceKeyInteger = (value) => {
|
|
107
|
+
if (value === undefined || !/^\d+$/u.test(value))
|
|
108
|
+
return null;
|
|
109
|
+
const parsed = Number(value);
|
|
110
|
+
return Number.isSafeInteger(parsed) ? parsed : null;
|
|
111
|
+
};
|
|
@@ -80,11 +80,27 @@ export class ZipArtifactReader {
|
|
|
80
80
|
}
|
|
81
81
|
const extractStream = (entry, signal) => {
|
|
82
82
|
const output = new PassThrough();
|
|
83
|
+
const controller = new AbortController();
|
|
84
|
+
const onAbort = () => {
|
|
85
|
+
controller.abort(signal?.reason);
|
|
86
|
+
// AbortSignal listeners dispatch synchronously, so this destroy wins the race
|
|
87
|
+
// against `getData` rejecting with its own AbortError. That ordering is what
|
|
88
|
+
// keeps the caller-visible failure typed as `cancelled`.
|
|
89
|
+
output.destroy(new ArtifactReaderFailure("cancelled", "ZIP operation cancelled"));
|
|
90
|
+
};
|
|
91
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
92
|
+
// `close` covers both a consumer walking away mid-entry and normal completion
|
|
93
|
+
// after `end()`; aborting then is harmless because `getData` has already
|
|
94
|
+
// resolved, and it releases the producer in the abandoned-consumer case.
|
|
95
|
+
output.once("close", () => {
|
|
96
|
+
signal?.removeEventListener("abort", onAbort);
|
|
97
|
+
controller.abort();
|
|
98
|
+
});
|
|
83
99
|
const writable = new WritableStream({
|
|
84
100
|
write: async (chunk) => {
|
|
85
101
|
abortIfNeeded(signal);
|
|
86
102
|
if (!output.write(Buffer.from(chunk)))
|
|
87
|
-
await once(output, "drain");
|
|
103
|
+
await once(output, "drain", { signal: controller.signal });
|
|
88
104
|
},
|
|
89
105
|
close: () => {
|
|
90
106
|
output.end();
|
|
@@ -95,6 +111,7 @@ const extractStream = (entry, signal) => {
|
|
|
95
111
|
});
|
|
96
112
|
void entry
|
|
97
113
|
.getData(writable, {
|
|
114
|
+
signal: controller.signal,
|
|
98
115
|
checkSignature: true,
|
|
99
116
|
checkOverlappingEntry: true,
|
|
100
117
|
onprogress: () => abortIfNeeded(signal),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
+
import { sanitizeBrowserUrl, } from "../domain/browserObservation.js";
|
|
2
3
|
const REDACTION_PREFIX = "[REDACTED:";
|
|
3
4
|
/** Resolved secret values kept only for one in-memory scenario session. */
|
|
4
5
|
export class BrowserScenarioSecrets {
|
|
@@ -10,7 +11,8 @@ export class BrowserScenarioSecrets {
|
|
|
10
11
|
const values = new Map();
|
|
11
12
|
for (const declaration of scenario.secrets) {
|
|
12
13
|
const value = environment[declaration.environment_variable];
|
|
13
|
-
if (
|
|
14
|
+
if (!Object.hasOwn(environment, declaration.environment_variable) ||
|
|
15
|
+
typeof value !== "string")
|
|
14
16
|
return undefined;
|
|
15
17
|
values.set(declaration.secret_id, value);
|
|
16
18
|
}
|
|
@@ -39,6 +41,31 @@ export class BrowserScenarioSecrets {
|
|
|
39
41
|
output = output.replaceAll(secret, `${REDACTION_PREFIX}${id}]`);
|
|
40
42
|
return output;
|
|
41
43
|
}
|
|
44
|
+
/** Remove only declared secret values from one URL and report that action. */
|
|
45
|
+
sanitizeUrl(value) {
|
|
46
|
+
let output = value;
|
|
47
|
+
const replacements = [...this.values].sort(([leftId, left], [rightId, right]) => right.length - left.length ||
|
|
48
|
+
(leftId < rightId ? -1 : leftId > rightId ? 1 : 0));
|
|
49
|
+
for (const [id, secret] of replacements) {
|
|
50
|
+
if (secret === "")
|
|
51
|
+
continue;
|
|
52
|
+
const marker = `${REDACTION_PREFIX}${id}]`;
|
|
53
|
+
const searchParamsValue = new URLSearchParams([["value", secret]])
|
|
54
|
+
.toString()
|
|
55
|
+
.slice("value=".length);
|
|
56
|
+
for (const candidate of new Set([
|
|
57
|
+
secret,
|
|
58
|
+
encodeURIComponent(secret),
|
|
59
|
+
searchParamsValue,
|
|
60
|
+
]))
|
|
61
|
+
output = output.replaceAll(candidate, marker);
|
|
62
|
+
}
|
|
63
|
+
const sanitized = sanitizeBrowserUrl(output);
|
|
64
|
+
return {
|
|
65
|
+
...sanitized,
|
|
66
|
+
redacted: sanitized.redacted || output !== value,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
42
69
|
fingerprint(value) {
|
|
43
70
|
for (const secret of this.values.values())
|
|
44
71
|
if (secret !== "" && value.includes(secret))
|
|
@@ -23,7 +23,7 @@ export const CDP_BROWSER_PROVIDER_IDENTITY = Object.freeze({
|
|
|
23
23
|
});
|
|
24
24
|
const IDENTITY = CDP_BROWSER_PROVIDER_IDENTITY;
|
|
25
25
|
const CLEANUP_DOMAINS = ["Network", "Debugger", "Runtime", "Page"];
|
|
26
|
-
/** Passive
|
|
26
|
+
/** Passive browser observation through a selected user-owned CDP endpoint. */
|
|
27
27
|
export class CdpBrowserProvider {
|
|
28
28
|
identity() {
|
|
29
29
|
return IDENTITY;
|
|
@@ -31,14 +31,17 @@ export class CdpBrowserProvider {
|
|
|
31
31
|
async listTargets(input, options = {}) {
|
|
32
32
|
try {
|
|
33
33
|
const discovery = await discoverCdpEndpoint(input.cdp_endpoint, "list_browser_targets", options.signal);
|
|
34
|
-
const
|
|
35
|
-
|
|
34
|
+
const selected = selectTargets(discovery, input.allowed_origins.length === 0
|
|
35
|
+
? undefined
|
|
36
|
+
: new Set(input.allowed_origins));
|
|
36
37
|
return ok(browserTargetListSchema.parse({
|
|
37
38
|
browser: discovery.version,
|
|
38
39
|
targets: selected.allowed,
|
|
39
40
|
excluded: selected.excluded,
|
|
40
41
|
limitations: [
|
|
41
|
-
|
|
42
|
+
input.allowed_origins.length === 0
|
|
43
|
+
? "All page targets with supported HTTP(S) URLs are listed."
|
|
44
|
+
: "Only page targets whose current URL matches an explicitly requested exact origin are listed.",
|
|
42
45
|
...(selected.unconnectable === 0
|
|
43
46
|
? []
|
|
44
47
|
: [
|
|
@@ -64,7 +67,12 @@ export class CdpBrowserProvider {
|
|
|
64
67
|
try {
|
|
65
68
|
const captured = await this.#capture(input, options, "analyze_web_bundle");
|
|
66
69
|
const sourceMaps = input.fetch_source_maps
|
|
67
|
-
? await fetchWebSourceMaps(captured.sourceMapRequests,
|
|
70
|
+
? await fetchWebSourceMaps(captured.sourceMapRequests, {
|
|
71
|
+
...input,
|
|
72
|
+
allowed_origins: input.allowed_origins.length > 0
|
|
73
|
+
? input.allowed_origins
|
|
74
|
+
: [captured.inspection.target.origin],
|
|
75
|
+
}, options.signal)
|
|
68
76
|
: undefined;
|
|
69
77
|
return ok(webBundleAnalysisSchema.parse(analyzeCapturedWebBundle(captured.inspection, sourceMaps)));
|
|
70
78
|
}
|
|
@@ -77,13 +85,14 @@ export class CdpBrowserProvider {
|
|
|
77
85
|
try {
|
|
78
86
|
const discovery = await discoverCdpEndpoint(input.cdp_endpoint, "observe_web_session", options.signal);
|
|
79
87
|
const target = authorizeTarget(discovery, input);
|
|
88
|
+
const scopedInput = scopeToTargetOrigin(input, target);
|
|
80
89
|
targetSession = await openCdpTargetSession(discovery, target, "observe_web_session", options.signal);
|
|
81
90
|
return ok(webObservationSessionSchema.parse(await observeCdpSession({
|
|
82
91
|
connection: targetSession.connection,
|
|
83
92
|
sessionId: targetSession.sessionId,
|
|
84
93
|
discovery,
|
|
85
94
|
target,
|
|
86
|
-
input,
|
|
95
|
+
input: scopedInput,
|
|
87
96
|
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
88
97
|
...(options.progress === undefined
|
|
89
98
|
? {}
|
|
@@ -95,7 +104,7 @@ export class CdpBrowserProvider {
|
|
|
95
104
|
}
|
|
96
105
|
finally {
|
|
97
106
|
if (targetSession !== undefined)
|
|
98
|
-
await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS);
|
|
107
|
+
await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS, options.signal);
|
|
99
108
|
}
|
|
100
109
|
}
|
|
101
110
|
async discoverWebMcpTools(input, options = {}) {
|
|
@@ -103,13 +112,14 @@ export class CdpBrowserProvider {
|
|
|
103
112
|
try {
|
|
104
113
|
const discovery = await discoverCdpEndpoint(input.cdp_endpoint, "discover_webmcp_tools", options.signal);
|
|
105
114
|
const target = authorizeTarget(discovery, input);
|
|
115
|
+
const scopedInput = scopeToTargetOrigin(input, target);
|
|
106
116
|
targetSession = await openCdpTargetSession(discovery, target, "discover_webmcp_tools", options.signal);
|
|
107
117
|
return ok(webMcpDiscoverySchema.parse(await discoverWebMcp({
|
|
108
118
|
connection: targetSession.connection,
|
|
109
119
|
sessionId: targetSession.sessionId,
|
|
110
120
|
discovery,
|
|
111
121
|
target,
|
|
112
|
-
input,
|
|
122
|
+
input: scopedInput,
|
|
113
123
|
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
114
124
|
...(options.progress === undefined
|
|
115
125
|
? {}
|
|
@@ -121,7 +131,7 @@ export class CdpBrowserProvider {
|
|
|
121
131
|
}
|
|
122
132
|
finally {
|
|
123
133
|
if (targetSession !== undefined)
|
|
124
|
-
await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS);
|
|
134
|
+
await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS, options.signal);
|
|
125
135
|
}
|
|
126
136
|
}
|
|
127
137
|
async compareCaptures(input) {
|
|
@@ -137,13 +147,14 @@ export class CdpBrowserProvider {
|
|
|
137
147
|
try {
|
|
138
148
|
const discovery = await discoverCdpEndpoint(input.cdp_endpoint, "capture_web_screenshot", options.signal);
|
|
139
149
|
const target = authorizeTarget(discovery, input);
|
|
150
|
+
const scopedInput = scopeToTargetOrigin(input, target);
|
|
140
151
|
targetSession = await openCdpTargetSession(discovery, target, "capture_web_screenshot", options.signal);
|
|
141
152
|
return ok(webScreenshotSchema.parse(await captureCdpScreenshot({
|
|
142
153
|
connection: targetSession.connection,
|
|
143
154
|
sessionId: targetSession.sessionId,
|
|
144
155
|
discovery,
|
|
145
156
|
target,
|
|
146
|
-
input,
|
|
157
|
+
input: scopedInput,
|
|
147
158
|
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
148
159
|
...(options.progress === undefined
|
|
149
160
|
? {}
|
|
@@ -155,7 +166,7 @@ export class CdpBrowserProvider {
|
|
|
155
166
|
}
|
|
156
167
|
finally {
|
|
157
168
|
if (targetSession !== undefined)
|
|
158
|
-
await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS);
|
|
169
|
+
await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS, options.signal);
|
|
159
170
|
}
|
|
160
171
|
}
|
|
161
172
|
async compareScreenshots(input) {
|
|
@@ -171,6 +182,7 @@ export class CdpBrowserProvider {
|
|
|
171
182
|
try {
|
|
172
183
|
const discovery = await discoverCdpEndpoint(input.cdp_endpoint, operation, options.signal);
|
|
173
184
|
const target = authorizeTarget(discovery, input);
|
|
185
|
+
const scopedInput = scopeToTargetOrigin(input, target);
|
|
174
186
|
targetSession = await openCdpTargetSession(discovery, target, operation, options.signal);
|
|
175
187
|
return await capturePage({
|
|
176
188
|
connection: targetSession.connection,
|
|
@@ -178,7 +190,7 @@ export class CdpBrowserProvider {
|
|
|
178
190
|
operation,
|
|
179
191
|
discovery,
|
|
180
192
|
target,
|
|
181
|
-
input,
|
|
193
|
+
input: scopedInput,
|
|
182
194
|
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
183
195
|
...(options.progress === undefined
|
|
184
196
|
? {}
|
|
@@ -187,7 +199,7 @@ export class CdpBrowserProvider {
|
|
|
187
199
|
}
|
|
188
200
|
finally {
|
|
189
201
|
if (targetSession !== undefined)
|
|
190
|
-
await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS);
|
|
202
|
+
await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS, options.signal);
|
|
191
203
|
}
|
|
192
204
|
}
|
|
193
205
|
}
|
|
@@ -207,7 +219,7 @@ const selectTargets = (discovery, allowedOrigins) => {
|
|
|
207
219
|
unsupportedUrl += 1;
|
|
208
220
|
continue;
|
|
209
221
|
}
|
|
210
|
-
if (!allowedOrigins.has(url.origin)) {
|
|
222
|
+
if (allowedOrigins !== undefined && !allowedOrigins.has(url.origin)) {
|
|
211
223
|
disallowedOrigin += 1;
|
|
212
224
|
continue;
|
|
213
225
|
}
|
|
@@ -242,10 +254,19 @@ const authorizeTarget = (discovery, input) => {
|
|
|
242
254
|
const origin = sanitizeBrowserUrl(target.url).origin;
|
|
243
255
|
if (target.type !== "page" ||
|
|
244
256
|
origin === null ||
|
|
245
|
-
|
|
257
|
+
(input.allowed_origins.length > 0 &&
|
|
258
|
+
!input.allowed_origins.includes(origin)))
|
|
246
259
|
throw new BrowserObservationError("inspect_web_page", "target_not_allowed");
|
|
247
260
|
return target;
|
|
248
261
|
};
|
|
262
|
+
const scopeToTargetOrigin = (input, target) => {
|
|
263
|
+
if (input.allowed_origins.length > 0)
|
|
264
|
+
return input;
|
|
265
|
+
const origin = sanitizeBrowserUrl(target.url).origin;
|
|
266
|
+
if (origin === null)
|
|
267
|
+
throw new BrowserObservationError("inspect_web_page", "target_not_allowed");
|
|
268
|
+
return { ...input, allowed_origins: [origin] };
|
|
269
|
+
};
|
|
249
270
|
const providerError = (cause, operation) => cause instanceof BrowserObservationError && cause.operation !== operation
|
|
250
271
|
? new BrowserObservationError(operation, cause.reason, { cause })
|
|
251
272
|
: cause instanceof AnalysisError
|
|
@@ -2,11 +2,13 @@ import { allowedSanitizedUrl, numberValue, recordValue, recordsValue, requiredRe
|
|
|
2
2
|
import { exclusionReasonForUrl } from "./CdpCaptureEventHelpers.js";
|
|
3
3
|
/** Normalize every allowed frame, optionally selecting a leading frame. */
|
|
4
4
|
export const captureFrames = (result, allowedOrigins, maximum, completeness) => {
|
|
5
|
-
const root = recordValue(
|
|
6
|
-
if (root === undefined)
|
|
5
|
+
const root = recordValue(recordValue(result)?.frameTree);
|
|
6
|
+
if (root === undefined) {
|
|
7
|
+
completeness?.exclude("frames", "invalid_protocol_value");
|
|
7
8
|
return { items: [] };
|
|
9
|
+
}
|
|
8
10
|
const items = [];
|
|
9
|
-
for (const tree of walkFrameTrees(root)) {
|
|
11
|
+
for (const tree of walkFrameTrees(root, () => completeness?.exclude("frames", "invalid_protocol_value"))) {
|
|
10
12
|
const frame = recordValue(tree.frame);
|
|
11
13
|
const frameId = stringValue(frame?.id);
|
|
12
14
|
const sanitized = allowedSanitizedUrl(frame?.url, allowedOrigins);
|
|
@@ -33,11 +35,13 @@ export const captureFrames = (result, allowedOrigins, maximum, completeness) =>
|
|
|
33
35
|
export const mainFrameUrl = (result) => stringValue(recordValue(recordValue(requiredRecord(result).frameTree)?.frame)?.url);
|
|
34
36
|
/** Normalize every allowed resource. */
|
|
35
37
|
export const captureResources = (result, allowedOrigins, completeness) => {
|
|
36
|
-
const root = recordValue(
|
|
37
|
-
if (root === undefined)
|
|
38
|
+
const root = recordValue(recordValue(result)?.frameTree);
|
|
39
|
+
if (root === undefined) {
|
|
40
|
+
completeness?.exclude("resources", "invalid_protocol_value");
|
|
38
41
|
return { items: [] };
|
|
42
|
+
}
|
|
39
43
|
const items = [];
|
|
40
|
-
for (const tree of walkFrameTrees(root)) {
|
|
44
|
+
for (const tree of walkFrameTrees(root, () => completeness?.exclude("resources", "invalid_protocol_value"))) {
|
|
41
45
|
for (const resource of recordsValue(tree.resources)) {
|
|
42
46
|
const url = allowedSanitizedUrl(resource.url, allowedOrigins);
|
|
43
47
|
if (url === undefined || url.origin === null) {
|
|
@@ -57,13 +61,23 @@ export const captureResources = (result, allowedOrigins, completeness) => {
|
|
|
57
61
|
}
|
|
58
62
|
return { items };
|
|
59
63
|
};
|
|
60
|
-
const walkFrameTrees = function* (root) {
|
|
64
|
+
export const walkFrameTrees = function* (root, onMalformedChild) {
|
|
61
65
|
const pending = [root];
|
|
62
66
|
while (pending.length > 0) {
|
|
63
67
|
const tree = pending.pop();
|
|
64
68
|
if (tree === undefined)
|
|
65
69
|
return;
|
|
66
|
-
const
|
|
70
|
+
const rawChildren = tree.childFrames;
|
|
71
|
+
if (rawChildren !== undefined && !Array.isArray(rawChildren))
|
|
72
|
+
onMalformedChild?.();
|
|
73
|
+
const children = Array.isArray(rawChildren)
|
|
74
|
+
? rawChildren.flatMap((child) => {
|
|
75
|
+
const parsed = recordValue(child);
|
|
76
|
+
if (parsed === undefined)
|
|
77
|
+
onMalformedChild?.();
|
|
78
|
+
return parsed === undefined ? [] : [parsed];
|
|
79
|
+
})
|
|
80
|
+
: [];
|
|
67
81
|
for (let index = children.length - 1; index >= 0; index -= 1) {
|
|
68
82
|
const child = children[index];
|
|
69
83
|
if (child !== undefined)
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { inferJsonShape } from "../domain/jsonShape.js";
|
|
2
2
|
import { safeResponseMetadata } from "./CdpSafeMetadata.js";
|
|
3
|
-
import { redactSensitiveText } from "./SensitiveTextCapture.js";
|
|
4
3
|
import { allowedSanitizedUrl, isHttpUrl, numberValue, recordValue, recordsValue, stringValue, } from "./CdpCaptureValues.js";
|
|
5
4
|
import { requestBodyShape } from "./CdpCaptureEventBodyShapes.js";
|
|
6
|
-
import { consolePrimitive, decodeBase64, exclusionReasonForUrl, executionContextKey, firstCallFrame, initiatorLocation, integerOrNull, } from "./CdpCaptureEventHelpers.js";
|
|
5
|
+
import { consolePrimitive, decodeBase64, exclusionReasonForUrl, executionContextKey, firstCallFrame, initiatorLocation, integerOrNull, isMainFrameNavigation, } from "./CdpCaptureEventHelpers.js";
|
|
7
6
|
export const handleExecutionContextCreated = (state, params) => {
|
|
8
7
|
const context = recordValue(params.context);
|
|
9
8
|
const identifier = numberValue(context?.id);
|
|
@@ -182,7 +181,7 @@ const captureConsoleText = (state, arguments_) => {
|
|
|
182
181
|
const primitive = consolePrimitive(argument);
|
|
183
182
|
if (primitive === undefined)
|
|
184
183
|
continue;
|
|
185
|
-
const text =
|
|
184
|
+
const text = primitive.text;
|
|
186
185
|
values.push({
|
|
187
186
|
argument_index: argumentIndex,
|
|
188
187
|
type: primitive.type,
|
|
@@ -261,10 +260,20 @@ export const handleWebSocketCreated = (state, params) => {
|
|
|
261
260
|
};
|
|
262
261
|
export const handleFrameNavigated = (state, params) => {
|
|
263
262
|
const frame = recordValue(params.frame);
|
|
264
|
-
if (
|
|
263
|
+
if (state.mainFrameId === undefined)
|
|
264
|
+
return;
|
|
265
|
+
if (!isMainFrameNavigation({ method: "Page.frameNavigated", params }, state.mainFrameId))
|
|
265
266
|
return;
|
|
266
|
-
state.navigationDuringCapture = true;
|
|
267
267
|
const rawUrl = stringValue(frame?.url);
|
|
268
|
+
const loaderId = stringValue(frame?.loaderId);
|
|
269
|
+
// `frameNavigated` re-fires for a document already reported (same URL and
|
|
270
|
+
// loader). Treating that as a navigation aborted a valid capture with
|
|
271
|
+
// `target_changed`, which is a false claim that the target moved.
|
|
272
|
+
const document = `${String(loaderId ?? "")}\0${String(rawUrl ?? "")}`;
|
|
273
|
+
if (state.committedDocument === document)
|
|
274
|
+
return;
|
|
275
|
+
state.committedDocument = document;
|
|
276
|
+
state.navigationDuringCapture = true;
|
|
268
277
|
if (isHttpUrl(rawUrl) &&
|
|
269
278
|
allowedSanitizedUrl(rawUrl, state.allowedOrigins) === undefined)
|
|
270
279
|
state.originViolation = true;
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import { isHttpUrl, numberValue, recordValue, recordsValue, stringValue, } from "./CdpCaptureValues.js";
|
|
2
|
+
/** Identify a top-level navigation event from its untrusted CDP envelope. */
|
|
3
|
+
export const isMainFrameNavigation = (event, mainFrameId) => {
|
|
4
|
+
const params = recordValue(event.params);
|
|
5
|
+
if (params === undefined)
|
|
6
|
+
return false;
|
|
7
|
+
const frameId = event.method === "Page.frameNavigated"
|
|
8
|
+
? stringValue(recordValue(params.frame)?.id)
|
|
9
|
+
: event.method === "Page.frameRequestedNavigation" ||
|
|
10
|
+
event.method === "Page.navigatedWithinDocument"
|
|
11
|
+
? stringValue(params.frameId)
|
|
12
|
+
: undefined;
|
|
13
|
+
return frameId === mainFrameId;
|
|
14
|
+
};
|
|
2
15
|
export const firstCallFrame = (value) => recordsValue(value?.callFrames)[0];
|
|
3
16
|
export const initiatorLocation = (initiator) => {
|
|
4
17
|
let stack = recordValue(initiator?.stack);
|
|
@@ -24,6 +24,7 @@ export class CdpCaptureEvents {
|
|
|
24
24
|
originViolation = false;
|
|
25
25
|
navigationDuringCapture = false;
|
|
26
26
|
mainFrameId = undefined;
|
|
27
|
+
committedDocument = undefined;
|
|
27
28
|
input;
|
|
28
29
|
allowedOrigins;
|
|
29
30
|
constructor(input, allowedOrigins) {
|
|
@@ -34,6 +35,7 @@ export class CdpCaptureEvents {
|
|
|
34
35
|
this.mainFrameId = frameId;
|
|
35
36
|
this.originViolation = false;
|
|
36
37
|
this.navigationDuringCapture = false;
|
|
38
|
+
this.committedDocument = undefined;
|
|
37
39
|
this.scripts.clear();
|
|
38
40
|
this.executionContextFrames.clear();
|
|
39
41
|
this.network.clear();
|
|
@@ -52,7 +54,14 @@ export class CdpCaptureEvents {
|
|
|
52
54
|
}
|
|
53
55
|
beginFinalCapture(frameId) {
|
|
54
56
|
this.mainFrameId = frameId;
|
|
55
|
-
|
|
57
|
+
// Deliberately does not clear `navigationDuringCapture`. A main-frame
|
|
58
|
+
// navigation observed during the observation window means the page never
|
|
59
|
+
// settled, and clearing the flag here reported the capture as clean while
|
|
60
|
+
// carrying pre-navigation scripts, network and console into the inventory
|
|
61
|
+
// of the new document. The caller now reports `target_changed` instead.
|
|
62
|
+
// `committedDocument` is dropped so the new document's frame events are
|
|
63
|
+
// compared against itself rather than the document we just left.
|
|
64
|
+
this.committedDocument = undefined;
|
|
56
65
|
}
|
|
57
66
|
ingest(event) {
|
|
58
67
|
const params = recordValue(event.params);
|
|
@@ -2,6 +2,7 @@ import { BrowserObservationError } from "../domain/errors.js";
|
|
|
2
2
|
import { CdpCaptureCompleteness } from "./CdpCaptureCompleteness.js";
|
|
3
3
|
import { canonicalJsonDigest } from "./CdpCanonicalJsonDigest.js";
|
|
4
4
|
import { delayWithCancellation, numberValue, recordValue, recordsValue, requiredRecord, stringValue, } from "./CdpCaptureValues.js";
|
|
5
|
+
import { walkFrameTrees } from "./CdpCaptureDocuments.js";
|
|
5
6
|
import { ingestElectronScriptEvent, } from "./CdpElectronScriptEvents.js";
|
|
6
7
|
import { captureElectronScripts } from "./CdpElectronScripts.js";
|
|
7
8
|
import { captureElectronWorkers } from "./CdpElectronWorkers.js";
|
|
@@ -15,7 +16,7 @@ export const inspectCdpElectronPage = async (context) => {
|
|
|
15
16
|
limitations: [
|
|
16
17
|
"Local file paths exposed by the selected CDP target are retained in the observation.",
|
|
17
18
|
"REA does not evaluate renderer JavaScript, invoke Electron APIs, navigate, click, or close the page.",
|
|
18
|
-
"
|
|
19
|
+
"Select include_script_sources to retain script contents.",
|
|
19
20
|
],
|
|
20
21
|
mainFrameId: undefined,
|
|
21
22
|
navigationDuringCapture: false,
|
|
@@ -132,13 +133,9 @@ const captureFrames = async (result, completeness) => {
|
|
|
132
133
|
const frameTree = recordValue(requiredRecord(result).frameTree);
|
|
133
134
|
if (frameTree === undefined)
|
|
134
135
|
throw new BrowserObservationError("inspect_web_page", "protocol_error");
|
|
135
|
-
const pending = [{ tree: frameTree, parent: null }];
|
|
136
136
|
const frames = [];
|
|
137
|
-
|
|
138
|
-
const
|
|
139
|
-
if (current === undefined)
|
|
140
|
-
break;
|
|
141
|
-
const frame = recordValue(current.tree.frame);
|
|
137
|
+
for (const tree of walkFrameTrees(frameTree, () => completeness.exclude("frames", "invalid_protocol_value"))) {
|
|
138
|
+
const frame = recordValue(tree.frame);
|
|
142
139
|
const frameId = stringValue(frame?.id);
|
|
143
140
|
const path = await authorizedElectronFile(stringValue(frame?.url) ?? "");
|
|
144
141
|
if (frameId === undefined || path === undefined) {
|
|
@@ -147,11 +144,9 @@ const captureFrames = async (result, completeness) => {
|
|
|
147
144
|
}
|
|
148
145
|
frames.push({
|
|
149
146
|
frame_id: frameId,
|
|
150
|
-
parent_frame_id:
|
|
147
|
+
parent_frame_id: stringValue(frame?.parentId) ?? null,
|
|
151
148
|
file_path: path,
|
|
152
149
|
});
|
|
153
|
-
for (const child of recordsValue(current.tree.childFrames))
|
|
154
|
-
pending.push({ tree: child, parent: frameId });
|
|
155
150
|
}
|
|
156
151
|
return frames;
|
|
157
152
|
};
|
|
@@ -91,11 +91,7 @@ export class CdpElectronProvider {
|
|
|
91
91
|
}
|
|
92
92
|
finally {
|
|
93
93
|
if (targetSession !== undefined)
|
|
94
|
-
await closeCdpTargetSession(targetSession, [
|
|
95
|
-
"Debugger",
|
|
96
|
-
"Runtime",
|
|
97
|
-
"Page",
|
|
98
|
-
]);
|
|
94
|
+
await closeCdpTargetSession(targetSession, ["Debugger", "Runtime", "Page"], options.signal);
|
|
99
95
|
}
|
|
100
96
|
}
|
|
101
97
|
}
|
|
@@ -51,7 +51,7 @@ const captureScriptSource = async (input, script) => {
|
|
|
51
51
|
return {
|
|
52
52
|
source: {
|
|
53
53
|
included: false,
|
|
54
|
-
reason: "source capture was not
|
|
54
|
+
reason: "source capture was not selected",
|
|
55
55
|
},
|
|
56
56
|
};
|
|
57
57
|
const result = requiredRecord(await input.connection.send("Debugger.getScriptSource", { scriptId: script.scriptId }, input.sessionId, input.signal));
|
|
@@ -82,8 +82,9 @@ const sanitizeSameOriginTitleUrl = (candidate, target) => {
|
|
|
82
82
|
catch {
|
|
83
83
|
return candidate;
|
|
84
84
|
}
|
|
85
|
-
return parsed.origin === target.origin &&
|
|
86
|
-
|
|
85
|
+
return parsed.origin === target.origin &&
|
|
86
|
+
(parsed.username !== "" || parsed.password !== "")
|
|
87
|
+
? sanitizeBrowserUrl(candidate).url
|
|
87
88
|
: candidate;
|
|
88
89
|
};
|
|
89
90
|
const escapeRegExp = (value) => value.replaceAll(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|