rea-agents 6.3.0 → 6.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/bridge/ghidra/ReaGhidraApplySeeds.java +151 -0
- package/bridge/ghidra/ReaGhidraBridge.java +597 -209
- package/bridge/ghidra/ReaGhidraNoReturnFix.java +123 -0
- package/dist/adb/AdbConfiguration.js +88 -0
- package/dist/adb/AdbDeviceOutput.js +186 -0
- package/dist/adb/AdbProvider.js +1190 -0
- package/dist/adb/AdbShellOutput.js +309 -0
- package/dist/android/AndroidTargetSnapshot.js +104 -22
- package/dist/android/JadxConfiguration.js +44 -24
- package/dist/android/JadxProvider.js +51 -19
- package/dist/apktool/ApktoolConfiguration.js +84 -0
- package/dist/apktool/ApktoolDecodeOutput.js +59 -0
- package/dist/apktool/ApktoolProvider.js +506 -0
- package/dist/application/AnalysisProvider.js +8 -2
- package/dist/application/AppBundleExecutable.js +27 -22
- package/dist/application/BinaryTargetResolver.js +22 -2
- package/dist/application/CapabilityInventory.js +11 -1
- package/dist/application/ClientConfigurationDocument.js +70 -0
- package/dist/application/ClientConfigurationFiles.js +91 -0
- package/dist/application/ClientRegistrationEnvironment.js +35 -0
- package/dist/application/ClientRegistrationStatus.js +66 -31
- package/dist/application/DirectAnalysis.js +2 -2
- package/dist/application/DirectAnalysisCleanup.js +1 -1
- package/dist/application/DirectAnalysisStatus.js +1 -1
- package/dist/application/Doctor.js +5 -3
- package/dist/application/DoctorDiagnostics.js +1 -1
- package/dist/application/EvidenceBundleCommands.js +6 -12
- package/dist/application/GeminiClientSettings.js +139 -0
- package/dist/application/HermesClientHome.js +115 -0
- package/dist/application/HopperDownload.js +39 -0
- package/dist/application/InvestigationProviders.js +6 -0
- package/dist/application/JsonFiles.js +6 -5
- package/dist/{cliJsonFile.js → application/JsonInputFile.js} +108 -35
- package/dist/application/LinuxHopper.js +4 -12
- package/dist/application/MacHopper.js +172 -149
- package/dist/application/MipsElfAbiFlags.js +140 -0
- package/dist/application/ProviderOperationExecution.js +31 -0
- package/dist/application/ReconstructionObligationCandidates.js +9 -3
- package/dist/application/ReferenceSourceImport.js +76 -29
- package/dist/application/ReferenceSourceImportEntries.js +18 -9
- package/dist/application/ReferenceSourceImportPolicy.js +99 -23
- package/dist/application/ReferenceSourceImportTypes.js +30 -22
- package/dist/application/ReferenceSourceVcsAdapter.js +145 -30
- package/dist/application/RegularFileRead.js +93 -7
- package/dist/application/Setup.js +54 -6
- package/dist/application/SetupClientConfiguration.js +116 -16
- package/dist/application/SetupHost.js +102 -24
- package/dist/application/SetupPlan.js +5 -8
- package/dist/application/SetupSkill.js +58 -39
- package/dist/application/SupportedClients.js +290 -65
- package/dist/application/Uninstall.js +158 -10
- package/dist/application/UpdateMaintenance.js +17 -21
- package/dist/application/Utf8JsonInput.js +7 -0
- package/dist/application/WebScriptExportService.js +131 -65
- package/dist/application/WebSourceLocationService.js +3 -0
- package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
- package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
- package/dist/application/analysisView/AnalysisViewService.js +40 -2
- package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
- package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
- package/dist/application/binary/AnalysisClientCleanup.js +0 -24
- package/dist/application/binary/BinarySession.js +2 -1
- package/dist/application/binaryDiagnostics/BinaryLayoutService.js +2 -1
- package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
- package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
- package/dist/application/binaryDiagnostics/RecordedCrashService.js +2 -1
- package/dist/application/evm/EvmInterfaceService.js +3 -0
- package/dist/application/firmware/FirmwareAnalysisService.js +3 -0
- package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
- package/dist/application/javascript/ElectronBoundaryGraphContext.js +3 -2
- package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
- package/dist/application/javascript/ElectronBoundaryGraphNative.js +19 -6
- package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
- package/dist/application/javascript/JavaScriptApplicationService.js +22 -11
- package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -30
- package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +67 -19
- package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
- package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
- package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +19 -16
- package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +258 -235
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +115 -26
- package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -1
- package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -4
- package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +9 -3
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +199 -61
- package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +12 -19
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +4 -1
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -3
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +5 -3
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +19 -8
- package/dist/application/jeb/JebAnalysisPort.js +1 -0
- package/dist/application/jeb/JebAnalysisService.js +13 -0
- package/dist/application/managed/ManagedApplicationGraphService.js +1 -1
- package/dist/application/native/NativeUiActionTrace.js +16 -8
- package/dist/application/native/NativeValueTrace.js +23 -6
- package/dist/application/process/ProcessCli.js +25 -20
- package/dist/artifacts/ArtifactPaths.js +129 -8
- package/dist/artifacts/ArtifactProvider.js +20 -15
- package/dist/artifacts/ArtifactReader.js +23 -0
- package/dist/artifacts/ArtifactResourceScope.js +100 -0
- package/dist/artifacts/AsarArtifactReader.js +176 -102
- package/dist/artifacts/AsarHeader.js +24 -0
- package/dist/artifacts/DirectoryArtifactReader.js +168 -65
- package/dist/artifacts/MachOSliceArtifactReader.js +116 -39
- package/dist/artifacts/NativeDmgArtifactReader.js +29 -22
- package/dist/artifacts/SafeOutputTree.js +245 -70
- package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
- package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
- package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
- package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
- package/dist/artifacts/ZipArtifactReader.js +77 -27
- package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +58 -18
- package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +62 -24
- package/dist/artifacts/apple/KeyedArchiveReader.js +32 -13
- package/dist/artifacts/extraction/ArtifactExtraction.js +110 -86
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +110 -43
- package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
- package/dist/artifacts/inventory/classify.js +75 -32
- package/dist/artifacts/inventory/hashStableRootArtifact.js +48 -15
- package/dist/artifacts/inventory/reader.js +13 -5
- package/dist/artifacts/inventory/scanCanonical.js +62 -25
- package/dist/artifacts/inventory/scanReader.js +38 -11
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +15 -9
- package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
- package/dist/browser/BrowserScenarioPartialObservation.js +8 -2
- package/dist/browser/BrowserScenarioSecrets.js +52 -37
- package/dist/browser/CdpBrowserProvider.js +5 -0
- package/dist/browser/CdpCaptureDocuments.js +40 -6
- package/dist/browser/CdpCaptureDomSvg.js +210 -0
- package/dist/browser/CdpCaptureEventBodyShapes.js +4 -8
- package/dist/browser/CdpCaptureEventHandlers.js +26 -9
- package/dist/browser/CdpCaptureEvents.js +4 -9
- package/dist/browser/CdpConnection.js +22 -5
- package/dist/browser/CdpPageCapture.js +1 -1
- package/dist/browser/CdpTargetSession.js +30 -34
- package/dist/browser/CdpWebMcpDiscovery.js +32 -10
- package/dist/browser/ElectronFileScope.js +99 -9
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +60 -4
- package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
- package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
- package/dist/browser/PlaywrightScenarioBrowser.js +69 -7
- package/dist/browser/PlaywrightScenarioSession.js +127 -54
- package/dist/browser/PlaywrightScenarioStorage.js +507 -0
- package/dist/browser/PngVisualDiff.js +198 -29
- package/dist/browser/WebSourceMapFetcher.js +3 -3
- package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
- package/dist/browser/assets/PublishWebScripts.js +75 -20
- package/dist/browser/assets/WebArtifactReads.js +23 -1
- package/dist/browser/assets/WebSourceLocationArtifacts.js +1 -0
- package/dist/browser/execution/CdpExecutionCapture.js +3 -3
- package/dist/browser/execution/CdpPreciseCoverage.js +5 -8
- package/dist/browser/history/HarCapture.js +14 -0
- package/dist/browser/history/HarCaptureProcess.js +2 -10
- package/dist/browser/history/MitmproxyCaptureAdapter.js +3 -1
- package/dist/browser/modules/WebModuleArtifacts.js +1 -0
- package/dist/cli/adbCommands.js +337 -0
- package/dist/cli/analysisViewCommands.js +39 -1
- package/dist/cli/apktoolCommands.js +53 -0
- package/dist/cli/artifactCommands.js +8 -11
- package/dist/cli/binaryDiagnosticsCommands.js +19 -1
- package/dist/cli/browserAdvancedCommands.js +65 -36
- package/dist/cli/coreBinaryCommands.js +0 -5
- package/dist/cli/coreNativeCommands.js +1 -14
- package/dist/cli/electronCommands.js +6 -1
- package/dist/cli/evmCommands.js +13 -4
- package/dist/cli/firmwareCommands.js +7 -2
- package/dist/cli/javascriptApplicationAnalysis.js +17 -1
- package/dist/cli/javascriptRecoveryCommands.js +22 -15
- package/dist/cli/jebCommands.js +99 -0
- package/dist/cli/jsonOutput.js +11 -4
- package/dist/cli/referenceSourceImportStatus.js +7 -0
- package/dist/cli/setupCommands.js +15 -3
- package/dist/cli/utilityCommands.js +66 -18
- package/dist/cli/webScriptCommands.js +20 -1
- package/dist/cli/webSourceLocationCommands.js +21 -9
- package/dist/cli.js +6 -0
- package/dist/cliBrowserScenarioCommands.js +2 -1
- package/dist/cliCommandNames.js +32 -0
- package/dist/cliJsonInput.js +2 -2
- package/dist/cliObservationOptions.js +3 -0
- package/dist/composition/adb.js +3 -0
- package/dist/composition/apktool.js +3 -0
- package/dist/composition/binaryDiagnostics.js +4 -0
- package/dist/composition/directAnalysis.js +12 -4
- package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
- package/dist/composition/jeb.js +6 -0
- package/dist/config/environment.js +10 -0
- package/dist/config/ghidraLanguageOverride.js +9 -0
- package/dist/config/mcpInputSchemaProfile.js +27 -0
- package/dist/config/parseConfig.js +28 -1
- package/dist/contracts/adb/adbToolContracts.js +353 -0
- package/dist/contracts/advertisedInputExamples.js +48 -0
- package/dist/contracts/analysisDetail.js +10 -0
- package/dist/contracts/analysisViewToolContracts.js +17 -2
- package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
- package/dist/contracts/artifactToolContracts.js +8 -5
- package/dist/contracts/browserToolContracts.js +1 -1
- package/dist/contracts/compactInputSchema.js +256 -0
- package/dist/contracts/functionWorkflowToolContracts.js +1 -1
- package/dist/contracts/inputSchemaPresentation.js +10 -10
- package/dist/contracts/javascript/electronToolContracts.js +15 -3
- package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
- package/dist/contracts/jeb/jebToolContracts.js +64 -0
- package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
- package/dist/contracts/officialToolContracts.js +5 -5
- package/dist/contracts/sessionToolContracts.js +2 -2
- package/dist/contracts/sessionToolSchemas.js +6 -2
- package/dist/contracts/toolContractExamples.js +6 -0
- package/dist/contracts/toolContractTypes.js +3 -0
- package/dist/contracts/toolContracts.js +6 -0
- package/dist/contracts/toolEffects.js +167 -0
- package/dist/contracts/toolOutputSchemaGroups.js +5 -3
- package/dist/contracts/toolSchemaMetadata.js +82 -7
- package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
- package/dist/domain/analysisErrorCleanup.js +29 -0
- package/dist/domain/analysisErrorPresentation.js +18 -6
- package/dist/domain/analysisErrorProjection.js +4 -1
- package/dist/domain/analysisSnapshot.js +2 -1
- package/dist/domain/analysisView/analysisView.js +52 -2
- package/dist/domain/analysisView/binaryLayoutView.js +2 -0
- package/dist/domain/analysisView/javascriptApplicationView.js +2 -0
- package/dist/domain/analysisView/nativeFunctionView.js +155 -0
- package/dist/domain/android/androidApplication.js +25 -20
- package/dist/domain/apktool/apktoolResourceAnalysis.js +77 -0
- package/dist/domain/apple/appleApplication.js +40 -23
- package/dist/domain/apple/appleBundleAnatomy.js +95 -28
- package/dist/domain/apple/dyldPaths.js +9 -1
- package/dist/domain/apple/dylibResolution.js +2 -2
- package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
- package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
- package/dist/domain/artifactComparison.js +35 -7
- package/dist/domain/artifactGraph.js +5 -3
- package/dist/domain/artifactIdentity.js +30 -2
- package/dist/domain/artifactInspection.js +3 -43
- package/dist/domain/artifactIntegrityPolicy.js +10 -0
- package/dist/domain/artifactInventoryEvidence.js +11 -12
- package/dist/domain/artifactPathSyntax.js +1 -1
- package/dist/domain/binaryTarget.js +16 -0
- package/dist/domain/binaryTargetTypes.js +8 -1
- package/dist/domain/browserObservationSchemas.js +8 -4
- package/dist/domain/canonicalJsonDigestSteps.js +34 -12
- package/dist/domain/compactStringIdentity.js +9 -0
- package/dist/domain/evidence.js +2 -1
- package/dist/domain/evidenceRecordSummary.js +144 -0
- package/dist/domain/inputIssueProjection.js +16 -1
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -13
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -20
- package/dist/domain/javascript/electronStaticAnalysisNative.js +70 -40
- package/dist/domain/javascript/electronStaticAnalysisValues.js +16 -0
- package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +4 -1
- package/dist/domain/javascript/javascriptApplicationChangeGraph.js +6 -6
- package/dist/domain/javascript/javascriptApplicationGraph.js +79 -18
- package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +28 -12
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -1
- package/dist/domain/javascript/javascriptAstFingerprint.js +58 -31
- package/dist/domain/javascript/javascriptAstValues.js +32 -0
- package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
- package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
- package/dist/domain/javascript/javascriptNativeHandoff.js +6 -1
- package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
- package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
- package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +7 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +8 -11
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +190 -33
- package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
- package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
- package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
- package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
- package/dist/domain/javascript/javascriptSemanticFingerprints.js +42 -41
- package/dist/domain/javascript/javascriptSemanticGraph.js +69 -23
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +2 -10
- package/dist/domain/javascript/javascriptSemanticIterationSources.js +40 -7
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +341 -87
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +78 -35
- package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
- package/dist/domain/javascript/javascriptSemanticObjects.js +7 -1
- package/dist/domain/javascript/javascriptSemanticProjection.js +52 -14
- package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +77 -0
- package/dist/domain/javascript/javascriptSemanticQuery.js +27 -29
- package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +1 -3
- package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
- package/dist/domain/javascript/javascriptSemanticReturns.js +13 -23
- package/dist/domain/javascript/javascriptSemanticState.js +22 -2
- package/dist/domain/javascript/javascriptSemanticTraversal.js +19 -1
- package/dist/domain/javascript/javascriptSemanticValues.js +47 -19
- package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
- package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
- package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +8 -6
- package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
- package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
- package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
- package/dist/domain/jeb/jebAnalysis.js +114 -0
- package/dist/domain/jsonShape.js +63 -52
- package/dist/domain/jsonValue.js +3 -0
- package/dist/domain/managed/managedApplicationGraph.js +37 -0
- package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
- package/dist/domain/managed/managedApplicationGraphNodes.js +32 -22
- package/dist/domain/managed/managedArtifact.js +1 -0
- package/dist/domain/managed/managedInspectionEvidence.js +13 -0
- package/dist/domain/native/nativeAotPe.js +1408 -0
- package/dist/domain/native/nativeInstruction.js +21 -0
- package/dist/domain/native/nativeMetadataRecovery.js +79 -6
- package/dist/domain/native/peResources.js +94 -0
- package/dist/domain/nativeConvention.js +33 -0
- package/dist/domain/process/processCapture.js +91 -1
- package/dist/domain/process/processCaptureExample.js +24 -0
- package/dist/domain/process/processCaptureValidation.js +79 -0
- package/dist/domain/process/processScenario.js +59 -7
- package/dist/domain/propertyListKeys.js +3 -1
- package/dist/domain/referenceSourceGraph.js +25 -16
- package/dist/domain/referenceSourceImportParsing.js +6 -3
- package/dist/domain/referenceSourcePathIdentity.js +22 -0
- package/dist/domain/referenceSourceRequireBindings.js +137 -0
- package/dist/domain/webBundleAnalyzerInspection.js +14 -2
- package/dist/domain/webCaptureDiff.js +102 -4
- package/dist/domain/webScriptExportError.js +10 -4
- package/dist/domain/webScriptExportPlan.js +7 -13
- package/dist/domain/zipPackageFormat.js +4 -1
- package/dist/domain/zodCollectionSteps.js +24 -0
- package/dist/dotnet/ManagedArtifactInspector.js +55 -43
- package/dist/dotnet/ManagedDecodeBudget.js +80 -0
- package/dist/dotnet/ManagedMemberInspector.js +13 -6
- package/dist/dotnet/ManagedMemberInspectorCore.js +2 -2
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +4 -2
- package/dist/dotnet/ManagedMemberRows.js +9 -4
- package/dist/dotnet/ManagedMetadataHeaps.js +15 -5
- package/dist/dotnet/ManagedMetadataInventoryRows.js +20 -11
- package/dist/dotnet/ManagedMetadataLayout.js +10 -4
- package/dist/dotnet/ManagedMethodBodyReader.js +8 -3
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +3 -2
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +49 -34
- package/dist/dotnet/ManagedPeReader.js +41 -25
- package/dist/dotnet/ManagedReaderFailure.js +2 -1
- package/dist/dotnet/ManagedStaticProvider.js +55 -24
- package/dist/evaluation/AgentEvaluationReport.js +9 -5
- package/dist/evaluation/CodexAgentEval.js +43 -13
- package/dist/evm/EvmoleFailures.js +0 -2
- package/dist/evm/EvmoleInterfaceProvider.js +67 -2
- package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
- package/dist/filesystem/OwnedFileHandle.js +36 -0
- package/dist/filesystem/RegularFile.js +33 -1
- package/dist/filesystem/StableFileHash.js +46 -0
- package/dist/filesystem/readFileHandleChunks.js +26 -0
- package/dist/firmware/FirmwareCommand.js +25 -3
- package/dist/firmware/FirmwareFiles.js +23 -8
- package/dist/firmware/FirmwareProvider.js +156 -32
- package/dist/firmware/FirmwarePublication.js +24 -3
- package/dist/firmware/FirmwareRelease.js +1 -0
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +55 -4
- package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
- package/dist/ghidra/GhidraClient.js +76 -4
- package/dist/ghidra/GhidraDiagnostics.js +11 -8
- package/dist/ghidra/GhidraFunctionValues.js +26 -2
- package/dist/ghidra/GhidraInstallation.js +1 -1
- package/dist/ghidra/GhidraInventoryValues.js +23 -1
- package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
- package/dist/ghidra/GhidraLauncher.js +80 -39
- package/dist/ghidra/GhidraLoadImageAttest.js +49 -2
- package/dist/ghidra/GhidraMipsProfile.js +79 -0
- package/dist/ghidra/GhidraProvider.js +57 -9
- package/dist/ghidra/GhidraProviderCapabilities.js +18 -8
- package/dist/ghidra/GhidraProviderClient.js +282 -21
- package/dist/ghidra/GhidraSessionValues.js +9 -2
- package/dist/hopper/HopperAnalysisProfile.js +2 -0
- package/dist/hopper/HopperClient.js +15 -6
- package/dist/hopper/HopperMachOImage.js +2 -0
- package/dist/hopper/HopperProvider.js +13 -2
- package/dist/ida/IdaOperationRunner.js +8 -2
- package/dist/ida/IdaProvider.js +7 -0
- package/dist/ida/IdaSessionClient.js +3 -1
- package/dist/ida/IdaWorkspace.js +4 -2
- package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +326 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +520 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +63 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +521 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +116 -0
- package/dist/javascript/recovery/RecoveryFiles.js +18 -7
- package/dist/javascript/recovery/WakaruCommand.js +22 -9
- package/dist/javascript/recovery/WakaruExecution.js +11 -7
- package/dist/javascript/recovery/WakaruProvider.js +139 -16
- package/dist/javascript/recovery/WakaruPublication.js +14 -4
- package/dist/javascript/recovery/WakaruRelease.js +10 -3
- package/dist/javascript/recovery/WakaruReport.js +12 -7
- package/dist/javascript/recovery/WakaruVersion.js +24 -0
- package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -3
- package/dist/javascript/sourceMaps/SourceMapDecoder.js +63 -7
- package/dist/javascript/sourceMaps/SourceMapFormat.js +15 -4
- package/dist/jeb/JebMcpConnection.js +179 -0
- package/dist/jeb/JebMcpEndpoint.js +40 -0
- package/dist/jeb/JebProvider.js +299 -0
- package/dist/mcpDoctor.js +15 -6
- package/dist/native/AppleDispatchCoverage.js +25 -12
- package/dist/native/AppleDispatchMetadata.js +14 -7
- package/dist/native/AppleMachoFixups.js +71 -15
- package/dist/native/AppleMachoSelection.js +23 -3
- package/dist/native/NativeMacOSProvider.js +91 -16
- package/dist/native/NativeMachoInspection.js +11 -7
- package/dist/native/NativeUiHelperRuntime.js +6 -1
- package/dist/native/NativeUiObservation.js +4 -3
- package/dist/native/pe/PeResourceLayout.js +120 -0
- package/dist/native/pe/PeResourceParser.js +286 -0
- package/dist/native/pe/PeResourcesProvider.js +63 -0
- package/dist/process/BoundedFileBytes.js +30 -7
- package/dist/process/DarwinProcessRunTokenReader.js +8 -3
- package/dist/process/OwnedCommand.js +4 -3
- package/dist/process/ProcessOwnership.js +104 -112
- package/dist/process/ProcessOwnershipObservation.js +96 -39
- package/dist/process/ProcessOwnershipProcessTree.js +4 -4
- package/dist/process/ProcessRunTokenObservations.js +48 -0
- package/dist/process/ProviderDiagnosticRedaction.js +17 -0
- package/dist/process/ProviderProcess.js +4 -3
- package/dist/process/capture/FilesystemSnapshot.js +28 -4
- package/dist/process/capture/ProcessCaptureLifecycle.js +350 -59
- package/dist/process/capture/ProcessCaptureProgress.js +62 -0
- package/dist/process/capture/ProcessHarness.js +194 -26
- package/dist/process/capture/ProcessNormalization.js +3 -1
- package/dist/process/capture/ProcessScenarioRuntimeValidation.js +5 -2
- package/dist/process/capture/TerminalRenderer.js +24 -7
- package/dist/reference/ReferenceSourceReader.js +22 -5
- package/dist/reference/ReferenceSourceReaderEntries.js +114 -51
- package/dist/reference/ReferenceSourceReaderErrors.js +12 -0
- package/dist/reference/ReferenceSourceReaderFile.js +50 -10
- package/dist/reference/ReferenceSourceReaderValidate.js +4 -4
- package/dist/server/EvidenceMcpServer.js +36 -1
- package/dist/server/admittedToolOperation.js +9 -0
- package/dist/server/contractToolHandler.js +21 -0
- package/dist/server/createServer.js +97 -25
- package/dist/server/registerAdbTools.js +36 -0
- package/dist/server/registerAnalysisViewTool.js +4 -9
- package/dist/server/registerAndroidTools.js +3 -12
- package/dist/server/registerApktoolTools.js +14 -0
- package/dist/server/registerApplicationTools/compareExportShapes.js +4 -6
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
- package/dist/server/registerApplicationTools/compareVersions.js +3 -2
- package/dist/server/registerApplicationTools/coverage.js +3 -2
- package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
- package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -2
- package/dist/server/registerApplicationTools/traceFeature.js +3 -2
- package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
- package/dist/server/registerArtifactComparisonTool.js +5 -2
- package/dist/server/registerBinaryDiagnosticsTools.js +16 -4
- package/dist/server/registerBrowserScenarioTool.js +10 -7
- package/dist/server/registerBrowserTools.js +12 -9
- package/dist/server/registerBundleComparisonTool.js +16 -2
- package/dist/server/registerCloseLifecycleTool.js +32 -3
- package/dist/server/registerElectronTools.js +28 -10
- package/dist/server/registerEvmTools.js +4 -9
- package/dist/server/registerFirmwareTools.js +3 -11
- package/dist/server/registerFunctionComparisonTool.js +5 -2
- package/dist/server/registerJavaScriptRecoveryTool.js +4 -9
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +9 -6
- package/dist/server/registerJebTools.js +16 -0
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -6
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -2
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +3 -2
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +3 -2
- package/dist/server/registerPeResourcesTool.js +9 -0
- package/dist/server/registerProcessComparisonTool.js +5 -2
- package/dist/server/registerRecordedCrashTools.js +4 -9
- package/dist/server/registerSessionRecordTools.js +2 -1
- package/dist/server/registerSessionTools.js +49 -18
- package/dist/server/registerWebModuleTool.js +4 -9
- package/dist/server/registerWebNetworkCaptureTool.js +4 -9
- package/dist/server/registerWebRuntimeTools.js +6 -5
- package/dist/server/registerWebScriptTool.js +6 -3
- package/dist/server/registerWebSourceLocationTool.js +4 -9
- package/dist/server/toolResult.js +21 -2
- package/dist/windows/WindowsPrivateRuntime.js +12 -5
- package/install.sh +7 -4
- package/licenses/nativeaot-parser-MIT.txt +28 -0
- package/native/windows/build/manifest.json +2 -2
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +33 -5
- package/scripts/rea.mjs +16 -1
- package/skills/reverse-engineer-anything/SKILL.md +52 -51
- package/skills/reverse-engineer-anything/references/connection-and-recovery.md +127 -0
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -0
- package/skills/reverse-engineer-anything/references/javascript-applications.md +92 -13
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +22 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { allowedSanitizedUrl, numberValue, recordValue, recordsValue, requiredRecord, cdpStringValue, } from "./CdpCaptureValues.js";
|
|
2
2
|
import { exclusionReasonForUrl } from "./CdpCaptureEventHelpers.js";
|
|
3
|
+
import { createDocumentSvgAncestry, domSvgLink } from "./CdpCaptureDomSvg.js";
|
|
3
4
|
/** Normalize every allowed frame, optionally selecting a leading frame. */
|
|
4
5
|
export const captureFrames = (result, allowedOrigins, maximum, completeness) => {
|
|
5
6
|
const root = recordValue(recordValue(result)?.frameTree);
|
|
@@ -114,21 +115,27 @@ export const captureDom = (result, allowedOrigins, input, completeness) => {
|
|
|
114
115
|
? documentNodes.attributes
|
|
115
116
|
: [];
|
|
116
117
|
const baseIndex = nodes.length;
|
|
118
|
+
const ancestry = createDocumentSvgAncestry({
|
|
119
|
+
nodeTypes,
|
|
120
|
+
nodeNames,
|
|
121
|
+
parents,
|
|
122
|
+
strings,
|
|
123
|
+
attributes,
|
|
124
|
+
});
|
|
117
125
|
total += nodeTypes.length;
|
|
118
126
|
for (let index = 0; index < nodeTypes.length; index += 1) {
|
|
119
127
|
const attributeIndexes = numberArray(attributes[index]);
|
|
120
128
|
const parent = Math.trunc(parents[index] ?? -1);
|
|
121
129
|
const nodeIndex = nodes.length;
|
|
122
130
|
const nodeName = indexedString(strings, nodeNames[index]);
|
|
131
|
+
const attributeNames = uniqueAttributeNames(attributeIndexes, strings);
|
|
123
132
|
nodes.push({
|
|
124
133
|
index: nodeIndex,
|
|
125
134
|
parent_index: parent < 0 ? -1 : baseIndex + parent,
|
|
126
135
|
node_type: Math.max(0, Math.trunc(nodeTypes[index] ?? 0)),
|
|
127
136
|
node_name: nodeName,
|
|
128
137
|
node_value_length: indexedString(strings, nodeValues[index]).length,
|
|
129
|
-
attribute_names:
|
|
130
|
-
.filter((_value, attributeIndex) => attributeIndex % 2 === 0)
|
|
131
|
-
.map((value) => indexedString(strings, value)),
|
|
138
|
+
attribute_names: attributeNames,
|
|
132
139
|
});
|
|
133
140
|
const metadata = domMetadata({
|
|
134
141
|
strings,
|
|
@@ -139,6 +146,7 @@ export const captureDom = (result, allowedOrigins, input, completeness) => {
|
|
|
139
146
|
nodeIndex,
|
|
140
147
|
nodeName,
|
|
141
148
|
allowedOrigins,
|
|
149
|
+
...domSvgLink(ancestry, index),
|
|
142
150
|
});
|
|
143
151
|
for (const url of metadata.urls) {
|
|
144
152
|
urls.push(url);
|
|
@@ -261,23 +269,49 @@ const indexedString = (strings, index) => {
|
|
|
261
269
|
const integer = numberValue(index);
|
|
262
270
|
return integer === undefined ? "" : (strings[Math.trunc(integer)] ?? "");
|
|
263
271
|
};
|
|
272
|
+
const uniqueAttributeNames = (attributeIndexes, strings) => {
|
|
273
|
+
const names = [];
|
|
274
|
+
const seen = new Set();
|
|
275
|
+
for (let index = 0; index < attributeIndexes.length; index += 2) {
|
|
276
|
+
const name = indexedString(strings, attributeIndexes[index]);
|
|
277
|
+
if (seen.has(name))
|
|
278
|
+
continue;
|
|
279
|
+
seen.add(name);
|
|
280
|
+
names.push(name);
|
|
281
|
+
}
|
|
282
|
+
return names;
|
|
283
|
+
};
|
|
264
284
|
const numberArray = (value) => Array.isArray(value)
|
|
265
285
|
? value.flatMap((item) => {
|
|
266
286
|
const number = numberValue(item);
|
|
267
287
|
return number === undefined ? [] : [number];
|
|
268
288
|
})
|
|
269
289
|
: [];
|
|
290
|
+
// Chrome reads an SVG XLink href only when href itself is absent, and an
|
|
291
|
+
// empty href still wins. HTML keeps the literal attribute name `xlink:href`.
|
|
292
|
+
// XML uses any prefix bound to the XLink namespace. Both are stored as href.
|
|
293
|
+
const hrefAttributeValue = (pairs, attribute, options) => {
|
|
294
|
+
const declared = pairs.get(attribute);
|
|
295
|
+
if (declared !== undefined)
|
|
296
|
+
return declared;
|
|
297
|
+
if (attribute !== "href" || !options.svgElement)
|
|
298
|
+
return undefined;
|
|
299
|
+
return options.xmlDocument ? options.xlinkHref : pairs.get("xlink:href");
|
|
300
|
+
};
|
|
270
301
|
const domMetadata = (options) => {
|
|
271
302
|
const { strings, attributes, baseUrl, documentUrl, nodeIndex, nodeName, allowedOrigins, } = options;
|
|
272
303
|
const pairs = new Map();
|
|
273
304
|
for (let index = 0; index + 1 < attributes.length; index += 2) {
|
|
274
|
-
|
|
305
|
+
// Chrome already folds HTML names; SVG/XML names remain case-sensitive.
|
|
306
|
+
const name = indexedString(strings, attributes[index]);
|
|
275
307
|
const value = indexedString(strings, attributes[index + 1]);
|
|
276
|
-
|
|
308
|
+
// HTML keeps the first declaration. A later repeat must not move dom_urls.
|
|
309
|
+
if (!pairs.has(name))
|
|
310
|
+
pairs.set(name, value);
|
|
277
311
|
}
|
|
278
312
|
const urls = [];
|
|
279
313
|
for (const attribute of domUrlAttributes) {
|
|
280
|
-
const value = pairs
|
|
314
|
+
const value = hrefAttributeValue(pairs, attribute, options);
|
|
281
315
|
if (value === undefined)
|
|
282
316
|
continue;
|
|
283
317
|
const tagName = nodeName.toLowerCase();
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { numberValue } from "./CdpCaptureValues.js";
|
|
2
|
+
const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
3
|
+
const XLINK_NAMESPACE = "http://www.w3.org/1999/xlink";
|
|
4
|
+
const UNRESOLVED = {
|
|
5
|
+
svgElement: false,
|
|
6
|
+
xlinkHref: undefined,
|
|
7
|
+
};
|
|
8
|
+
const stringAt = (strings, index) => {
|
|
9
|
+
const integer = numberValue(index);
|
|
10
|
+
return integer === undefined ? "" : (strings[Math.trunc(integer)] ?? "");
|
|
11
|
+
};
|
|
12
|
+
const numberArray = (value) => Array.isArray(value)
|
|
13
|
+
? value.flatMap((item) => {
|
|
14
|
+
const number = numberValue(item);
|
|
15
|
+
return number === undefined ? [] : [number];
|
|
16
|
+
})
|
|
17
|
+
: [];
|
|
18
|
+
// DOMSnapshot has no namespace URI. HTML documents use uppercase `HTML` and
|
|
19
|
+
// the parser's local names. XML documents preserve prefixed names and xmlns
|
|
20
|
+
// declarations, including those on standalone SVG roots.
|
|
21
|
+
const xmlDocument = (nodes) => {
|
|
22
|
+
const documentIndex = nodes.nodeTypes.findIndex((nodeType) => Math.trunc(nodeType) === 9);
|
|
23
|
+
if (documentIndex < 0)
|
|
24
|
+
return false;
|
|
25
|
+
for (let index = 0; index < nodes.nodeTypes.length; index += 1) {
|
|
26
|
+
if (Math.trunc(nodes.nodeTypes[index] ?? 0) !== 1)
|
|
27
|
+
continue;
|
|
28
|
+
if (Math.trunc(nodes.parents[index] ?? -1) !== documentIndex)
|
|
29
|
+
continue;
|
|
30
|
+
const name = stringAt(nodes.strings, nodes.nodeNames[index]);
|
|
31
|
+
if (name === "HTML")
|
|
32
|
+
return false;
|
|
33
|
+
if (name === "html" || name.includes(":"))
|
|
34
|
+
return true;
|
|
35
|
+
// Explicit namespaces also identify standalone SVG and other XML roots.
|
|
36
|
+
// Namespace-free synthetic snapshots retain the legacy HTML behavior.
|
|
37
|
+
const attributes = numberArray(nodes.attributes[index]);
|
|
38
|
+
return attributes.some((value, offset) => offset % 2 === 0 &&
|
|
39
|
+
xmlnsPrefix(stringAt(nodes.strings, value)) !== undefined);
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
};
|
|
43
|
+
export const createDocumentSvgAncestry = (nodes) => {
|
|
44
|
+
const xml = xmlDocument(nodes);
|
|
45
|
+
return {
|
|
46
|
+
xml,
|
|
47
|
+
nodes,
|
|
48
|
+
svgContexts: new Map(),
|
|
49
|
+
xmlLinks: xml ? resolveXmlElements(nodes) : new Map(),
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
export const domSvgLink = (ancestry, index) => {
|
|
53
|
+
if (!ancestry.xml) {
|
|
54
|
+
return {
|
|
55
|
+
svgElement: elementInSvgContext(index, ancestry.nodes, ancestry.svgContexts),
|
|
56
|
+
xmlDocument: false,
|
|
57
|
+
xlinkHref: undefined,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const resolved = ancestry.xmlLinks.get(index) ?? UNRESOLVED;
|
|
61
|
+
return {
|
|
62
|
+
svgElement: resolved.svgElement,
|
|
63
|
+
xmlDocument: true,
|
|
64
|
+
xlinkHref: resolved.xlinkHref,
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
// Chrome's HTML parser records SVG local names (`svg`, `foreignObject`).
|
|
68
|
+
// Descendants of foreignObject are HTML until a nested `svg`.
|
|
69
|
+
const elementInSvgContext = (index, nodes, contexts) => {
|
|
70
|
+
let current = index;
|
|
71
|
+
const seen = new Set();
|
|
72
|
+
let inSvg = false;
|
|
73
|
+
while (current >= 0 &&
|
|
74
|
+
current < nodes.nodeNames.length &&
|
|
75
|
+
!seen.has(current)) {
|
|
76
|
+
const cached = contexts.get(current);
|
|
77
|
+
if (cached !== undefined) {
|
|
78
|
+
inSvg = cached;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
seen.add(current);
|
|
82
|
+
if (stringAt(nodes.strings, nodes.nodeNames[current]) === "svg") {
|
|
83
|
+
inSvg = true;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
const parent = Math.trunc(nodes.parents[current] ?? -1);
|
|
87
|
+
if (parent < 0 || parent === current)
|
|
88
|
+
break;
|
|
89
|
+
if (stringAt(nodes.strings, nodes.nodeNames[parent]) === "foreignObject")
|
|
90
|
+
break;
|
|
91
|
+
current = parent;
|
|
92
|
+
}
|
|
93
|
+
// Cache the entire examined chain, including forward references and cycles,
|
|
94
|
+
// so shared ancestors are examined once per document.
|
|
95
|
+
for (const node of seen)
|
|
96
|
+
contexts.set(node, inSvg);
|
|
97
|
+
return inSvg;
|
|
98
|
+
};
|
|
99
|
+
// Walk parent-before-child with one mutable namespace environment. Restore
|
|
100
|
+
// declarations on exit so siblings retain their own scope. Only declarations
|
|
101
|
+
// on the active path are retained, rather than cumulative maps at every node.
|
|
102
|
+
const resolveXmlElements = (nodes) => {
|
|
103
|
+
const children = new Map();
|
|
104
|
+
const pending = [];
|
|
105
|
+
for (let node = 0; node < nodes.nodeNames.length; node += 1) {
|
|
106
|
+
const parent = Math.trunc(nodes.parents[node] ?? -1);
|
|
107
|
+
if (parent < 0)
|
|
108
|
+
pending.push({ node });
|
|
109
|
+
else if (parent < nodes.nodeNames.length && parent !== node) {
|
|
110
|
+
const siblings = children.get(parent);
|
|
111
|
+
if (siblings === undefined)
|
|
112
|
+
children.set(parent, [node]);
|
|
113
|
+
else
|
|
114
|
+
siblings.push(node);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const bindings = new Map();
|
|
118
|
+
const resolved = new Map();
|
|
119
|
+
while (pending.length > 0) {
|
|
120
|
+
const step = pending.pop();
|
|
121
|
+
if (step === undefined)
|
|
122
|
+
break;
|
|
123
|
+
if ("restore" in step) {
|
|
124
|
+
for (const { prefix, previous } of step.restore) {
|
|
125
|
+
if (previous === undefined)
|
|
126
|
+
bindings.delete(prefix);
|
|
127
|
+
else
|
|
128
|
+
bindings.set(prefix, previous);
|
|
129
|
+
}
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const { node } = step;
|
|
133
|
+
const attributes = numberArray(nodes.attributes[node]);
|
|
134
|
+
const restore = applyDeclarations(bindings, attributes, nodes.strings);
|
|
135
|
+
const svgElement = Math.trunc(nodes.nodeTypes[node] ?? 0) === 1 &&
|
|
136
|
+
elementNamespace(stringAt(nodes.strings, nodes.nodeNames[node]), bindings) === SVG_NAMESPACE;
|
|
137
|
+
resolved.set(node, {
|
|
138
|
+
svgElement,
|
|
139
|
+
xlinkHref: svgElement
|
|
140
|
+
? xlinkHrefValue(attributes, nodes.strings, bindings)
|
|
141
|
+
: undefined,
|
|
142
|
+
});
|
|
143
|
+
pending.push({ restore });
|
|
144
|
+
for (const child of children.get(node) ?? [])
|
|
145
|
+
pending.push({ node: child });
|
|
146
|
+
}
|
|
147
|
+
// Cycles (including self-parents) and dangling chains cannot reach a root,
|
|
148
|
+
// so remain unresolved instead of deriving URLs from an invalid ancestry.
|
|
149
|
+
return resolved;
|
|
150
|
+
};
|
|
151
|
+
const applyDeclarations = (bindings, attributes, strings) => {
|
|
152
|
+
const restore = [];
|
|
153
|
+
const seen = new Set();
|
|
154
|
+
for (let index = 0; index + 1 < attributes.length; index += 2) {
|
|
155
|
+
const prefix = xmlnsPrefix(stringAt(strings, attributes[index]));
|
|
156
|
+
if (prefix === undefined || seen.has(prefix))
|
|
157
|
+
continue;
|
|
158
|
+
seen.add(prefix);
|
|
159
|
+
restore.push({ prefix, previous: bindings.get(prefix) });
|
|
160
|
+
const value = stringAt(strings, attributes[index + 1]);
|
|
161
|
+
if (value.length === 0)
|
|
162
|
+
bindings.delete(prefix);
|
|
163
|
+
else
|
|
164
|
+
bindings.set(prefix, value);
|
|
165
|
+
}
|
|
166
|
+
return restore;
|
|
167
|
+
};
|
|
168
|
+
const xmlnsPrefix = (name) => {
|
|
169
|
+
if (name === "xmlns")
|
|
170
|
+
return "";
|
|
171
|
+
if (!name.startsWith("xmlns:"))
|
|
172
|
+
return undefined;
|
|
173
|
+
const prefix = name.slice("xmlns:".length);
|
|
174
|
+
if (prefix.length === 0 || prefix === "xmlns" || prefix.includes(":"))
|
|
175
|
+
return undefined;
|
|
176
|
+
return prefix;
|
|
177
|
+
};
|
|
178
|
+
const elementNamespace = (nodeName, bindings) => {
|
|
179
|
+
const colon = nodeName.indexOf(":");
|
|
180
|
+
if (colon < 0)
|
|
181
|
+
return bindings.get("") ?? "";
|
|
182
|
+
const prefix = nodeName.slice(0, colon);
|
|
183
|
+
const local = nodeName.slice(colon + 1);
|
|
184
|
+
if (prefix.length === 0 ||
|
|
185
|
+
local.length === 0 ||
|
|
186
|
+
local.includes(":") ||
|
|
187
|
+
prefix === "xmlns")
|
|
188
|
+
return "";
|
|
189
|
+
return bindings.get(prefix) ?? "";
|
|
190
|
+
};
|
|
191
|
+
// First prefixed href bound to the XLink namespace. Duplicate names keep the
|
|
192
|
+
// earlier value. Plain href is applied by the caller and wins even when empty.
|
|
193
|
+
const xlinkHrefValue = (attributes, strings, bindings) => {
|
|
194
|
+
const seen = new Set();
|
|
195
|
+
for (let index = 0; index + 1 < attributes.length; index += 2) {
|
|
196
|
+
const name = stringAt(strings, attributes[index]);
|
|
197
|
+
if (seen.has(name))
|
|
198
|
+
continue;
|
|
199
|
+
seen.add(name);
|
|
200
|
+
const colon = name.indexOf(":");
|
|
201
|
+
if (colon <= 0)
|
|
202
|
+
continue;
|
|
203
|
+
const prefix = name.slice(0, colon);
|
|
204
|
+
const local = name.slice(colon + 1);
|
|
205
|
+
if (local !== "href" || bindings.get(prefix) !== XLINK_NAMESPACE)
|
|
206
|
+
continue;
|
|
207
|
+
return stringAt(strings, attributes[index + 1]);
|
|
208
|
+
}
|
|
209
|
+
return undefined;
|
|
210
|
+
};
|
|
@@ -15,8 +15,7 @@ export const ingestResponseBodyShape = (state, requestId, value) => {
|
|
|
15
15
|
invalidResponseBodyShape(state, requestId);
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
updateResponseBodyShape(state, requestId, inferred.shape);
|
|
18
|
+
updateResponseBodyShape(state, requestId, inferJsonShape(decoded));
|
|
20
19
|
};
|
|
21
20
|
export const requestBodyShape = (state, request) => {
|
|
22
21
|
if (!state.input.include_json_body_shapes)
|
|
@@ -24,10 +23,10 @@ export const requestBodyShape = (state, request) => {
|
|
|
24
23
|
const body = cdpStringValue(request.postData);
|
|
25
24
|
if (!isJsonContentType(recordValue(request.headers)) || body === undefined)
|
|
26
25
|
return { status: "unavailable", request: null, response: null };
|
|
27
|
-
const
|
|
26
|
+
const shape = inferJsonShape(body);
|
|
28
27
|
return {
|
|
29
|
-
status:
|
|
30
|
-
request:
|
|
28
|
+
status: shape === null ? "unavailable" : "included",
|
|
29
|
+
request: shape,
|
|
31
30
|
response: null,
|
|
32
31
|
};
|
|
33
32
|
};
|
|
@@ -46,9 +45,6 @@ export const updateResponseBodyShape = (state, requestId, response) => {
|
|
|
46
45
|
body_shapes: { status, request, response },
|
|
47
46
|
});
|
|
48
47
|
};
|
|
49
|
-
const inferBodyShape = (text) => {
|
|
50
|
-
return { shape: inferJsonShape(text) };
|
|
51
|
-
};
|
|
52
48
|
const invalidResponseBodyShape = (state, requestId) => {
|
|
53
49
|
updateResponseBodyShape(state, requestId, null);
|
|
54
50
|
state.completeness.exclude("json_body_shapes", "invalid_protocol_value");
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { sanitizeBrowserUrl } from "../domain/browserObservation.js";
|
|
1
2
|
import { inferJsonShape } from "../domain/jsonShape.js";
|
|
2
3
|
import { safeResponseMetadata } from "./CdpSafeMetadata.js";
|
|
3
4
|
import { allowedSanitizedUrl, isHttpUrl, numberValue, recordValue, recordsValue, scriptMetadataValues, cdpStringValue, } from "./CdpCaptureValues.js";
|
|
@@ -13,6 +14,7 @@ export const handleExecutionContextCreated = (state, params) => {
|
|
|
13
14
|
frameId === undefined)
|
|
14
15
|
return;
|
|
15
16
|
const key = String(identifier);
|
|
17
|
+
// New contexts may reuse an id. Scripts already parsed keep the frame stored on them.
|
|
16
18
|
state.executionContextFrames.set(key, frameId);
|
|
17
19
|
};
|
|
18
20
|
export const handleExecutionContextDestroyed = (state, params) => {
|
|
@@ -39,6 +41,7 @@ export const handleScriptParsed = (state, params) => {
|
|
|
39
41
|
state.completeness.exclude("scripts", exclusionReasonForUrl(rawUrl));
|
|
40
42
|
return;
|
|
41
43
|
}
|
|
44
|
+
const executionContext = executionContextKey(params.executionContextId);
|
|
42
45
|
const baseScript = {
|
|
43
46
|
scriptId,
|
|
44
47
|
rawUrl,
|
|
@@ -46,7 +49,10 @@ export const handleScriptParsed = (state, params) => {
|
|
|
46
49
|
origin: sanitized.origin,
|
|
47
50
|
...scriptMetadataValues(params),
|
|
48
51
|
language: cdpStringValue(params.scriptLanguage) ?? null,
|
|
49
|
-
executionContextKey:
|
|
52
|
+
executionContextKey: executionContext,
|
|
53
|
+
frameId: executionContext === null
|
|
54
|
+
? null
|
|
55
|
+
: (state.executionContextFrames.get(executionContext) ?? null),
|
|
50
56
|
};
|
|
51
57
|
const baseBytes = scriptMetadataStringBytes(baseScript);
|
|
52
58
|
const sourceMapDeclared = typeof params.sourceMapURL === "string" && params.sourceMapURL.length > 0;
|
|
@@ -79,7 +85,8 @@ const scriptMetadataStringBytes = (script) => stringByteLength(script.scriptId)
|
|
|
79
85
|
stringByteLength(script.origin) +
|
|
80
86
|
stringByteLength(script.hash) +
|
|
81
87
|
stringByteLength(script.language) +
|
|
82
|
-
stringByteLength(script.executionContextKey)
|
|
88
|
+
stringByteLength(script.executionContextKey) +
|
|
89
|
+
stringByteLength(script.frameId);
|
|
83
90
|
const stringByteLength = (value) => value === null ? 0 : Buffer.byteLength(value, "utf8");
|
|
84
91
|
const sourceMapForScript = (value, scriptUrl, state, remainingBytes) => {
|
|
85
92
|
const declaredUrl = cdpStringValue(value);
|
|
@@ -350,8 +357,10 @@ const captureConsoleText = (state, arguments_) => {
|
|
|
350
357
|
};
|
|
351
358
|
export const handleWebSocketFrame = (state, params, direction) => {
|
|
352
359
|
const requestId = cdpStringValue(params.requestId);
|
|
353
|
-
if (requestId === undefined
|
|
354
|
-
|
|
360
|
+
if (requestId === undefined)
|
|
361
|
+
return;
|
|
362
|
+
const connection = state.webSocketConnectionsById.get(requestId);
|
|
363
|
+
if (connection === undefined)
|
|
355
364
|
return;
|
|
356
365
|
const response = recordValue(params.response);
|
|
357
366
|
const payload = cdpStringValue(response?.payloadData) ?? "";
|
|
@@ -359,11 +368,10 @@ export const handleWebSocketFrame = (state, params, direction) => {
|
|
|
359
368
|
const decoded = opcode === 1 ? undefined : decodeBase64(payload);
|
|
360
369
|
if (opcode !== 1 && decoded === undefined)
|
|
361
370
|
state.completeness.exclude("websocket_frames", "invalid_protocol_value");
|
|
362
|
-
|
|
363
|
-
request_id: requestId,
|
|
371
|
+
connection.events.push({
|
|
364
372
|
direction,
|
|
365
373
|
opcode,
|
|
366
|
-
payload_bytes: opcode === 1 ? Buffer.byteLength(payload) : (decoded?.byteLength ??
|
|
374
|
+
payload_bytes: opcode === 1 ? Buffer.byteLength(payload) : (decoded?.byteLength ?? null),
|
|
367
375
|
payload_shape: captureWebSocketShape(state, payload, opcode),
|
|
368
376
|
});
|
|
369
377
|
};
|
|
@@ -389,9 +397,10 @@ export const handleWebSocketCreated = (state, params) => {
|
|
|
389
397
|
state.completeness.exclude("websocket_connections", "invalid_protocol_value");
|
|
390
398
|
return;
|
|
391
399
|
}
|
|
400
|
+
const sourceUrl = sanitizeBrowserUrl(rawUrl).url;
|
|
392
401
|
let parsed;
|
|
393
402
|
try {
|
|
394
|
-
parsed = new URL(
|
|
403
|
+
parsed = new URL(sourceUrl);
|
|
395
404
|
}
|
|
396
405
|
catch (cause) {
|
|
397
406
|
// Unparseable URLs are recorded as unsupported, not as failures.
|
|
@@ -411,7 +420,15 @@ export const handleWebSocketCreated = (state, params) => {
|
|
|
411
420
|
state.completeness.exclude("websocket_connections", "disallowed_origin");
|
|
412
421
|
return;
|
|
413
422
|
}
|
|
414
|
-
state.
|
|
423
|
+
if (state.webSocketConnectionsById.has(requestId)) {
|
|
424
|
+
state.completeness.exclude("websocket_connections", "invalid_protocol_value");
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
state.webSocketConnectionsById.set(requestId, {
|
|
428
|
+
request_id: requestId,
|
|
429
|
+
url: sourceUrl,
|
|
430
|
+
events: [],
|
|
431
|
+
});
|
|
415
432
|
};
|
|
416
433
|
export const handleFrameNavigated = (state, params) => {
|
|
417
434
|
const frame = recordValue(params.frame);
|
|
@@ -16,9 +16,8 @@ export class CdpCaptureEvents {
|
|
|
16
16
|
network = new Map();
|
|
17
17
|
networkRequestTimestamps = new Map();
|
|
18
18
|
malformedRedirectRequestIds = new Set();
|
|
19
|
-
|
|
19
|
+
webSocketConnectionsById = new Map();
|
|
20
20
|
console = [];
|
|
21
|
-
websockets = [];
|
|
22
21
|
responseMetadata = [];
|
|
23
22
|
agentHints = [];
|
|
24
23
|
completeness = new CdpCaptureCompleteness([
|
|
@@ -54,9 +53,8 @@ export class CdpCaptureEvents {
|
|
|
54
53
|
this.network.clear();
|
|
55
54
|
this.networkRequestTimestamps.clear();
|
|
56
55
|
this.malformedRedirectRequestIds.clear();
|
|
57
|
-
this.
|
|
56
|
+
this.webSocketConnectionsById.clear();
|
|
58
57
|
this.console.length = 0;
|
|
59
|
-
this.websockets.length = 0;
|
|
60
58
|
this.responseMetadata.length = 0;
|
|
61
59
|
this.agentHints.length = 0;
|
|
62
60
|
this.completeness.reset();
|
|
@@ -136,11 +134,8 @@ export class CdpCaptureEvents {
|
|
|
136
134
|
}
|
|
137
135
|
/** Resolve a transient execution context to one already authorized frame. */
|
|
138
136
|
frameForScript(script, allowedFrameIds) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const frameId = this.executionContextFrames.get(script.executionContextKey);
|
|
142
|
-
return frameId !== undefined && allowedFrameIds.has(frameId)
|
|
143
|
-
? frameId
|
|
137
|
+
return script.frameId !== null && allowedFrameIds.has(script.frameId)
|
|
138
|
+
? script.frameId
|
|
144
139
|
: null;
|
|
145
140
|
}
|
|
146
141
|
responseBodyRequestIds() {
|
|
@@ -5,6 +5,10 @@ import { BrowserObservationError } from "../domain/browserObservationError.js";
|
|
|
5
5
|
import { CdpCommandRejection } from "./CdpCommandRejection.js";
|
|
6
6
|
import {} from "../domain/browserObservationErrors.js";
|
|
7
7
|
import { safeParseJson } from "../domain/safeJson.js";
|
|
8
|
+
import { WEB_RUNTIME_LIMITS } from "../domain/webRuntime.js";
|
|
9
|
+
// ws currently stores maxPayload as a signed 32-bit integer. Larger values can
|
|
10
|
+
// wrap to a negative number, which disables its limit check.
|
|
11
|
+
const MAX_WEBSOCKET_PAYLOAD_BYTES = 0x7fff_ffff;
|
|
8
12
|
/** Correlated JSON-RPC transport for one CDP target operation. */
|
|
9
13
|
export class CdpConnection {
|
|
10
14
|
socket;
|
|
@@ -16,6 +20,7 @@ export class CdpConnection {
|
|
|
16
20
|
#protocolFailureListeners = new Set();
|
|
17
21
|
#nextId = 1;
|
|
18
22
|
#closed = false;
|
|
23
|
+
#closePromise;
|
|
19
24
|
#protocolFailed = false;
|
|
20
25
|
#transportFailure = "disconnected";
|
|
21
26
|
constructor(socket, operation, maxPayloadBytes) {
|
|
@@ -32,13 +37,20 @@ export class CdpConnection {
|
|
|
32
37
|
static async connect(url, operation, signal, limits) {
|
|
33
38
|
if (signal?.aborted === true)
|
|
34
39
|
throw new AnalysisCancelledError(operation);
|
|
40
|
+
const maxPayloadBytes = limits === undefined
|
|
41
|
+
? WEB_RUNTIME_LIMITS.protocolBytes
|
|
42
|
+
: limits.maxPayloadBytes;
|
|
43
|
+
if (!Number.isSafeInteger(maxPayloadBytes) ||
|
|
44
|
+
maxPayloadBytes <= 0 ||
|
|
45
|
+
maxPayloadBytes > MAX_WEBSOCKET_PAYLOAD_BYTES)
|
|
46
|
+
throw new RangeError(`CDP maxPayloadBytes must be a positive safe integer no greater than ${String(MAX_WEBSOCKET_PAYLOAD_BYTES)}.`);
|
|
35
47
|
const socket = new WebSocket(url, {
|
|
36
48
|
handshakeTimeout: 0,
|
|
37
|
-
maxPayload:
|
|
49
|
+
maxPayload: maxPayloadBytes,
|
|
38
50
|
perMessageDeflate: false,
|
|
39
51
|
});
|
|
40
52
|
await waitForOpen(socket, operation, signal);
|
|
41
|
-
return new CdpConnection(socket, operation,
|
|
53
|
+
return new CdpConnection(socket, operation, maxPayloadBytes);
|
|
42
54
|
}
|
|
43
55
|
/** Subscribe to validated CDP event envelopes. */
|
|
44
56
|
onEvent(listener) {
|
|
@@ -109,9 +121,14 @@ export class CdpConnection {
|
|
|
109
121
|
});
|
|
110
122
|
}
|
|
111
123
|
/** Close only REA's socket; never close the browser or selected page. */
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
124
|
+
close() {
|
|
125
|
+
this.#closePromise ??= this.#closeTransport().catch((cause) => {
|
|
126
|
+
this.#closePromise = undefined;
|
|
127
|
+
throw cause;
|
|
128
|
+
});
|
|
129
|
+
return this.#closePromise;
|
|
130
|
+
}
|
|
131
|
+
async #closeTransport() {
|
|
115
132
|
this.#closed = true;
|
|
116
133
|
this.#failPending("disconnected");
|
|
117
134
|
if (this.socket.readyState === WebSocket.CLOSED)
|
|
@@ -188,7 +188,7 @@ const normalizedInspection = (state, captured) => ({
|
|
|
188
188
|
resources: [...captured.resources],
|
|
189
189
|
network: {
|
|
190
190
|
requests: [...state.events.network.values()],
|
|
191
|
-
|
|
191
|
+
websocket_connections: [...state.events.webSocketConnectionsById.values()],
|
|
192
192
|
coverage_started_at: state.startedAt,
|
|
193
193
|
prior_activity_available: false,
|
|
194
194
|
},
|
|
@@ -20,43 +20,39 @@ export const openCdpTargetSession = async (discovery, target, operation, signal,
|
|
|
20
20
|
/** Disable enabled domains, detach browser sessions, and close REA's socket. */
|
|
21
21
|
export const closeCdpTargetSession = async (targetSession, enabledDomains, signal) => {
|
|
22
22
|
const { connection, sessionId } = targetSession;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
await connection.send(`${domain}.disable`, {}, sessionId, signal);
|
|
30
|
-
}
|
|
31
|
-
catch (cause) {
|
|
32
|
-
// best-effort cleanup: domain disable continues to detach/close boundary.
|
|
33
|
-
void cause;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
if (signal?.aborted === true) {
|
|
37
|
-
await closeCancelledTargetSession(targetSession, []);
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
if (sessionId !== undefined)
|
|
41
|
-
try {
|
|
42
|
-
await connection.send("Target.detachFromTarget", { sessionId }, undefined, signal);
|
|
43
|
-
}
|
|
44
|
-
catch (cause) {
|
|
45
|
-
// best-effort cleanup: closing REA's socket is the final cleanup boundary.
|
|
46
|
-
void cause;
|
|
47
|
-
}
|
|
48
|
-
await connection.close();
|
|
49
|
-
};
|
|
50
|
-
const closeCancelledTargetSession = async ({ connection, sessionId }, enabledDomains) => {
|
|
51
|
-
const commands = enabledDomains.map((domain) => connection.send(`${domain}.disable`, {}, sessionId));
|
|
52
|
-
if (sessionId !== undefined)
|
|
53
|
-
commands.push(connection.send("Target.detachFromTarget", { sessionId }));
|
|
54
|
-
const settled = Promise.allSettled(commands);
|
|
23
|
+
const cleanup = new AbortController();
|
|
24
|
+
const domainSignal = signal === undefined
|
|
25
|
+
? cleanup.signal
|
|
26
|
+
: AbortSignal.any([cleanup.signal, signal]);
|
|
27
|
+
const timeout = setTimeout(() => cleanup.abort(), 1_000);
|
|
28
|
+
timeout.unref();
|
|
55
29
|
try {
|
|
56
|
-
|
|
30
|
+
if (signal?.aborted !== true) {
|
|
31
|
+
for (const domain of enabledDomains) {
|
|
32
|
+
if (domainSignal.aborted)
|
|
33
|
+
break;
|
|
34
|
+
try {
|
|
35
|
+
await connection.send(`${domain}.disable`, {}, sessionId, domainSignal);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// Best-effort domain cleanup; transport close is the definitive boundary.
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Cancellation skips optional domain shutdown but still releases the
|
|
43
|
+
// attached session using its independent, bounded cleanup signal.
|
|
44
|
+
if (!cleanup.signal.aborted && sessionId !== undefined)
|
|
45
|
+
try {
|
|
46
|
+
await connection.send("Target.detachFromTarget", { sessionId }, undefined, cleanup.signal);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Best-effort detach; transport close is the definitive boundary.
|
|
50
|
+
}
|
|
57
51
|
}
|
|
58
52
|
finally {
|
|
59
|
-
|
|
53
|
+
clearTimeout(timeout);
|
|
54
|
+
cleanup.abort();
|
|
55
|
+
await connection.close();
|
|
60
56
|
}
|
|
61
57
|
};
|
|
62
58
|
const attachedSessionId = (value, operation) => {
|