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
|
@@ -223,24 +223,29 @@ const assertStableAuthorizedFrame = async (context, initialUrl, origins) => {
|
|
|
223
223
|
};
|
|
224
224
|
const ingestWebMcpEvent = (options) => {
|
|
225
225
|
const { event, input, frames, tools, completeness, transientFrames, resolvedTransientFrames, } = options;
|
|
226
|
+
if (event.method !== "WebMCP.toolsAdded" &&
|
|
227
|
+
event.method !== "WebMCP.toolsRemoved")
|
|
228
|
+
return;
|
|
226
229
|
const params = recordValue(event.params);
|
|
227
|
-
if (params === undefined)
|
|
230
|
+
if (params === undefined) {
|
|
231
|
+
completeness.exclude("webmcp_tools", "invalid_protocol_value");
|
|
228
232
|
return;
|
|
233
|
+
}
|
|
229
234
|
if (event.method === "WebMCP.toolsRemoved") {
|
|
230
|
-
for (const removed of
|
|
235
|
+
for (const removed of webMcpEventTools(params.tools, completeness)) {
|
|
231
236
|
const name = cdpStringValue(removed.name);
|
|
232
237
|
const frameId = cdpStringValue(removed.frameId);
|
|
233
|
-
if (name === undefined || frameId === undefined)
|
|
238
|
+
if (name === undefined || frameId === undefined) {
|
|
239
|
+
completeness.exclude("webmcp_tools", "invalid_protocol_value");
|
|
234
240
|
continue;
|
|
241
|
+
}
|
|
235
242
|
for (const [key, tool] of tools)
|
|
236
243
|
if (tool.name === name && tool.frame_id === frameId)
|
|
237
244
|
tools.delete(key);
|
|
238
245
|
}
|
|
239
246
|
return;
|
|
240
247
|
}
|
|
241
|
-
|
|
242
|
-
return;
|
|
243
|
-
for (const declared of recordsValue(params.tools)) {
|
|
248
|
+
for (const declared of webMcpEventTools(params.tools, completeness)) {
|
|
244
249
|
const frameId = cdpStringValue(declared.frameId);
|
|
245
250
|
if (frameId !== undefined && transientFrames.has(frameId)) {
|
|
246
251
|
if (!resolvedTransientFrames.has(frameId))
|
|
@@ -254,14 +259,31 @@ const ingestWebMcpEvent = (options) => {
|
|
|
254
259
|
tools.set(normalized.tool_key, normalized);
|
|
255
260
|
}
|
|
256
261
|
};
|
|
262
|
+
const webMcpEventTools = (value, completeness) => {
|
|
263
|
+
if (!Array.isArray(value)) {
|
|
264
|
+
completeness.exclude("webmcp_tools", "invalid_protocol_value");
|
|
265
|
+
return [];
|
|
266
|
+
}
|
|
267
|
+
const records = [];
|
|
268
|
+
for (const item of value) {
|
|
269
|
+
const record = recordValue(item);
|
|
270
|
+
if (record === undefined) {
|
|
271
|
+
completeness.exclude("webmcp_tools", "invalid_protocol_value");
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
records.push(record);
|
|
275
|
+
}
|
|
276
|
+
return records;
|
|
277
|
+
};
|
|
257
278
|
const normalizeTool = (value, input, frames, completeness) => {
|
|
258
279
|
const frameId = cdpStringValue(value.frameId);
|
|
259
280
|
const name = cdpStringValue(value.name);
|
|
260
281
|
const frame = frameId === undefined ? undefined : frames.get(frameId);
|
|
261
|
-
if (frameId === undefined ||
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
282
|
+
if (frameId === undefined || name === undefined) {
|
|
283
|
+
completeness.exclude("webmcp_tools", "invalid_protocol_value");
|
|
284
|
+
return undefined;
|
|
285
|
+
}
|
|
286
|
+
if (frame?.origin === null || frame === undefined) {
|
|
265
287
|
completeness.exclude("webmcp_tools", "out_of_target_scope");
|
|
266
288
|
return undefined;
|
|
267
289
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { realpath, stat } from "node:fs/promises";
|
|
2
|
-
import { isAbsolute } from "node:path";
|
|
1
|
+
import { open, realpath, stat } from "node:fs/promises";
|
|
2
|
+
import { isAbsolute, join, sep } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { admitAsarHeader, MAX_ASAR_HEADER_BYTES, } from "../artifacts/AsarHeader.js";
|
|
4
5
|
/** Resolve one local file URL while rejecting remote hosts and encoded separators. */
|
|
5
6
|
export const authorizedElectronFile = async (value) => {
|
|
6
7
|
if (/%(?:2f|5c)/iu.test(value))
|
|
@@ -30,16 +31,105 @@ export const authorizedElectronFile = async (value) => {
|
|
|
30
31
|
}
|
|
31
32
|
if (!isAbsolute(path) || path.includes("\0"))
|
|
32
33
|
return undefined;
|
|
33
|
-
let canonical;
|
|
34
34
|
try {
|
|
35
|
-
if (
|
|
36
|
-
return
|
|
37
|
-
canonical = await realpath(path);
|
|
35
|
+
if ((await stat(path)).isFile())
|
|
36
|
+
return await realpath(path);
|
|
38
37
|
}
|
|
39
38
|
catch (cause) {
|
|
40
|
-
//
|
|
39
|
+
// Electron serves packaged pages from inside app.asar, which the host
|
|
40
|
+
// filesystem cannot stat; resolve those through the archive header below.
|
|
41
41
|
void cause;
|
|
42
|
-
return undefined;
|
|
43
42
|
}
|
|
44
|
-
return
|
|
43
|
+
return await authorizedAsarMember(path);
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Resolve `<archive>.asar/<member>` the way Electron's file protocol does: the
|
|
47
|
+
* first `.asar` path component that is a regular file is the archive, and the
|
|
48
|
+
* remainder must name a regular file in its header (packed or unpacked).
|
|
49
|
+
*/
|
|
50
|
+
const authorizedAsarMember = async (path) => {
|
|
51
|
+
const segments = path.split(sep);
|
|
52
|
+
for (let index = 1; index < segments.length - 1; index += 1) {
|
|
53
|
+
if (!(segments[index] ?? "").toLowerCase().endsWith(".asar"))
|
|
54
|
+
continue;
|
|
55
|
+
const archive = segments.slice(0, index + 1).join(sep);
|
|
56
|
+
const member = segments.slice(index + 1);
|
|
57
|
+
if (member.some((part) => part === "" || part === "." || part === ".."))
|
|
58
|
+
return undefined;
|
|
59
|
+
try {
|
|
60
|
+
const metadata = await stat(archive);
|
|
61
|
+
if (!metadata.isFile())
|
|
62
|
+
continue;
|
|
63
|
+
const canonical = await realpath(archive);
|
|
64
|
+
const files = await asarFiles(canonical, metadata);
|
|
65
|
+
return isAsarRegularFile(files, member)
|
|
66
|
+
? join(canonical, ...member)
|
|
67
|
+
: undefined;
|
|
68
|
+
}
|
|
69
|
+
catch (cause) {
|
|
70
|
+
// An unreadable or malformed archive cannot authorize its members.
|
|
71
|
+
void cause;
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return undefined;
|
|
76
|
+
};
|
|
77
|
+
// This is a retained-memory budget for JSON headers, shared across all archives.
|
|
78
|
+
const MAX_CACHED_HEADERS = 8;
|
|
79
|
+
const headerCache = new Map();
|
|
80
|
+
const archiveIdentity = (metadata) => `${String(metadata.dev)}:${String(metadata.ino)}:${String(metadata.size)}:${String(metadata.mtimeMs)}`;
|
|
81
|
+
/** Read the two Chromium pickle headers on one handle before allocating JSON. */
|
|
82
|
+
const asarFiles = async (archive, metadata) => {
|
|
83
|
+
const identity = archiveIdentity(metadata);
|
|
84
|
+
const cached = headerCache.get(archive);
|
|
85
|
+
if (cached?.identity === identity)
|
|
86
|
+
return cached.files;
|
|
87
|
+
const handle = await open(archive, "r");
|
|
88
|
+
let files;
|
|
89
|
+
let jsonBytes;
|
|
90
|
+
try {
|
|
91
|
+
const opened = await handle.stat();
|
|
92
|
+
if (!opened.isFile() || archiveIdentity(opened) !== identity)
|
|
93
|
+
throw new Error("ASAR identity changed before header read");
|
|
94
|
+
const admitted = await admitAsarHeader(handle);
|
|
95
|
+
jsonBytes = admitted.jsonBytes;
|
|
96
|
+
const json = Buffer.alloc(jsonBytes);
|
|
97
|
+
let offset = 0;
|
|
98
|
+
while (offset < json.length) {
|
|
99
|
+
const part = await handle.read(json, offset, json.length - offset, 16 + offset);
|
|
100
|
+
if (part.bytesRead === 0)
|
|
101
|
+
throw new Error("Truncated ASAR JSON header");
|
|
102
|
+
offset += part.bytesRead;
|
|
103
|
+
}
|
|
104
|
+
if (archiveIdentity(await handle.stat()) !== identity)
|
|
105
|
+
throw new Error("ASAR identity changed during header read");
|
|
106
|
+
const parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(json));
|
|
107
|
+
if (!isRecord(parsed) || !isRecord(parsed.files))
|
|
108
|
+
throw new Error("ASAR header has no file tree");
|
|
109
|
+
files = parsed.files;
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
await handle.close();
|
|
113
|
+
}
|
|
114
|
+
headerCache.delete(archive);
|
|
115
|
+
headerCache.set(archive, { identity, files, bytes: jsonBytes });
|
|
116
|
+
const retainedBytes = () => [...headerCache.values()].reduce((sum, entry) => sum + entry.bytes, 0);
|
|
117
|
+
while (headerCache.size > MAX_CACHED_HEADERS ||
|
|
118
|
+
retainedBytes() > MAX_ASAR_HEADER_BYTES)
|
|
119
|
+
headerCache.delete(headerCache.keys().next().value ?? archive);
|
|
120
|
+
return files;
|
|
121
|
+
};
|
|
122
|
+
const isAsarRegularFile = (files, member) => {
|
|
123
|
+
let node = { files };
|
|
124
|
+
for (const part of member) {
|
|
125
|
+
const children = isRecord(node) ? node.files : undefined;
|
|
126
|
+
if (!isRecord(children) || !Object.hasOwn(children, part))
|
|
127
|
+
return false;
|
|
128
|
+
node = children[part];
|
|
129
|
+
}
|
|
130
|
+
return (isRecord(node) &&
|
|
131
|
+
typeof node.size === "number" &&
|
|
132
|
+
!("files" in node) &&
|
|
133
|
+
!("link" in node));
|
|
45
134
|
};
|
|
135
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -135,11 +135,14 @@ const globalCompleteness = (scenario, session, steps) => {
|
|
|
135
135
|
missing.push("events");
|
|
136
136
|
return classifyBrowserScenarioCompleteness(missing, truncated);
|
|
137
137
|
};
|
|
138
|
-
const runScenario = async (openSession, scenario, options) => {
|
|
138
|
+
const runScenario = async (openSession, scenario, options, retainCleanup) => {
|
|
139
139
|
if (options.signal?.aborted === true)
|
|
140
140
|
throw new BrowserObservationError(OPERATION, "cancelled");
|
|
141
141
|
const startedAt = Date.now();
|
|
142
|
-
const session = await openSession(scenario,
|
|
142
|
+
const session = await openSession(scenario, {
|
|
143
|
+
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
144
|
+
retainCleanup,
|
|
145
|
+
});
|
|
143
146
|
const steps = [];
|
|
144
147
|
let operationOutcome = { ok: true };
|
|
145
148
|
try {
|
|
@@ -172,6 +175,7 @@ const runScenario = async (openSession, scenario, options) => {
|
|
|
172
175
|
}
|
|
173
176
|
catch (cause) {
|
|
174
177
|
cleanupOutcome = { ok: false, cause };
|
|
178
|
+
retainCleanup(() => session.close());
|
|
175
179
|
}
|
|
176
180
|
if (!cleanupOutcome.ok) {
|
|
177
181
|
const cleanup = browserScenarioCleanupObservation(cleanupOutcome.cause);
|
|
@@ -226,15 +230,33 @@ const runScenario = async (openSession, scenario, options) => {
|
|
|
226
230
|
/** Controlled Playwright/CDP scenario driver with exact process ownership. */
|
|
227
231
|
export class PlaywrightBrowserScenarioProvider {
|
|
228
232
|
openSession;
|
|
233
|
+
#tail = Promise.resolve();
|
|
234
|
+
#closing = false;
|
|
235
|
+
#closePromise;
|
|
236
|
+
#pendingCleanup = new Set();
|
|
229
237
|
constructor(openSession) {
|
|
230
238
|
this.openSession = openSession;
|
|
231
239
|
}
|
|
232
240
|
identity() {
|
|
233
241
|
return PLAYWRIGHT_BROWSER_SCENARIO_PROVIDER_IDENTITY;
|
|
234
242
|
}
|
|
235
|
-
|
|
243
|
+
captureScenario(scenario, options = {}) {
|
|
244
|
+
if (this.#closing)
|
|
245
|
+
return Promise.resolve(err(this.#closedError()));
|
|
246
|
+
const operation = this.#tail.then(() => this.#closing
|
|
247
|
+
? err(this.#closedError())
|
|
248
|
+
: this.#captureScenario(scenario, options));
|
|
249
|
+
this.#tail = operation.then(() => undefined, () => undefined);
|
|
250
|
+
return operation;
|
|
251
|
+
}
|
|
252
|
+
async #captureScenario(scenario, options) {
|
|
253
|
+
const pending = await this.#retryCleanup();
|
|
254
|
+
if (pending !== undefined)
|
|
255
|
+
return err(pending);
|
|
236
256
|
try {
|
|
237
|
-
return ok(await runScenario(this.openSession, scenario, options)
|
|
257
|
+
return ok(await runScenario(this.openSession, scenario, options, (close) => {
|
|
258
|
+
this.#pendingCleanup.add(close);
|
|
259
|
+
}));
|
|
238
260
|
}
|
|
239
261
|
catch (cause) {
|
|
240
262
|
if (cause instanceof AnalysisError)
|
|
@@ -242,4 +264,38 @@ export class PlaywrightBrowserScenarioProvider {
|
|
|
242
264
|
return err(new ProviderAdapterError(PLAYWRIGHT_BROWSER_SCENARIO_PROVIDER_IDENTITY.id, OPERATION, { cause }));
|
|
243
265
|
}
|
|
244
266
|
}
|
|
267
|
+
async close() {
|
|
268
|
+
this.#closing = true;
|
|
269
|
+
this.#closePromise ??= this.#tail
|
|
270
|
+
.then(async () => {
|
|
271
|
+
const failure = await this.#retryCleanup();
|
|
272
|
+
if (failure !== undefined)
|
|
273
|
+
throw failure;
|
|
274
|
+
})
|
|
275
|
+
.catch((cause) => {
|
|
276
|
+
this.#closePromise = undefined;
|
|
277
|
+
throw cause;
|
|
278
|
+
});
|
|
279
|
+
return this.#closePromise;
|
|
280
|
+
}
|
|
281
|
+
#closedError() {
|
|
282
|
+
return new BrowserObservationError(OPERATION, "cleanup_failed", {
|
|
283
|
+
detail: "Browser scenario provider is closing.",
|
|
284
|
+
cleanup: { reason: "Provider is closing", resources: [] },
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
async #retryCleanup() {
|
|
288
|
+
for (const pending of this.#pendingCleanup) {
|
|
289
|
+
try {
|
|
290
|
+
await pending();
|
|
291
|
+
this.#pendingCleanup.delete(pending);
|
|
292
|
+
}
|
|
293
|
+
catch (cause) {
|
|
294
|
+
return cause instanceof AnalysisError
|
|
295
|
+
? cause
|
|
296
|
+
: new ProviderAdapterError(PLAYWRIGHT_BROWSER_SCENARIO_PROVIDER_IDENTITY.id, OPERATION, { cause });
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return undefined;
|
|
300
|
+
}
|
|
245
301
|
}
|
|
@@ -181,18 +181,23 @@ export class PlaywrightElectronActiveProvider {
|
|
|
181
181
|
return outcome;
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
184
|
+
/** Clean up an Electron launch. Windows signals a process only after lineage is verified. */
|
|
185
|
+
export const cleanupElectronProcesses = async (ownership, lineage, host = {
|
|
186
|
+
platform: process.platform,
|
|
187
|
+
terminateTree: cleanupWindowsProcessTree,
|
|
188
|
+
}) => {
|
|
189
|
+
if (host.platform === "win32") {
|
|
190
|
+
// An empty Windows process table is not ownership proof for this PID.
|
|
189
191
|
if (lineage?.status !== "verified")
|
|
190
192
|
return {
|
|
191
193
|
cleaned: false,
|
|
192
194
|
reason: "owned Electron lineage was unavailable; helper cleanup was not proven",
|
|
193
195
|
};
|
|
196
|
+
const root = await host.terminateTree(ownership.leaderPid);
|
|
197
|
+
if (!root.cleaned)
|
|
198
|
+
return root;
|
|
194
199
|
for (const descendant of lineage.lineage.descendants) {
|
|
195
|
-
const result = await
|
|
200
|
+
const result = await host.terminateTree(descendant.pid);
|
|
196
201
|
if (!result.cleaned)
|
|
197
202
|
return result;
|
|
198
203
|
}
|
|
@@ -120,20 +120,20 @@ const captureStorage = async (input) => {
|
|
|
120
120
|
}))()`));
|
|
121
121
|
const value = {
|
|
122
122
|
cookies: cookies.map((cookie) => ({
|
|
123
|
-
name: cookie.name,
|
|
124
|
-
domain: cookie.domain,
|
|
125
|
-
path: cookie.path,
|
|
123
|
+
name: secrets.redact(cookie.name),
|
|
124
|
+
domain: secrets.redact(cookie.domain),
|
|
125
|
+
path: secrets.redact(cookie.path),
|
|
126
126
|
secure: cookie.secure,
|
|
127
127
|
http_only: cookie.httpOnly,
|
|
128
128
|
same_site: cookie.sameSite,
|
|
129
129
|
...secrets.fingerprint(cookie.value),
|
|
130
130
|
})),
|
|
131
131
|
local_storage: pageStorage.local_storage.map(([name, value]) => ({
|
|
132
|
-
name,
|
|
132
|
+
name: secrets.redact(name),
|
|
133
133
|
...secrets.fingerprint(value),
|
|
134
134
|
})),
|
|
135
135
|
session_storage: pageStorage.session_storage.map(([name, value]) => ({
|
|
136
|
-
name,
|
|
136
|
+
name: secrets.redact(name),
|
|
137
137
|
...secrets.fingerprint(value),
|
|
138
138
|
})),
|
|
139
139
|
};
|
|
@@ -3,6 +3,7 @@ import { tmpdir } from "node:os";
|
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
4
|
import { chromium, } from "playwright-core";
|
|
5
5
|
import { AnalysisError } from "../domain/analysisErrorBase.js";
|
|
6
|
+
import { isLiteralLoopbackHostname } from "../domain/browserObservation.js";
|
|
6
7
|
import { BrowserObservationError } from "../domain/browserObservationError.js";
|
|
7
8
|
import { withPlaywrightExecutionBoundary } from "./PlaywrightExecutionBoundary.js";
|
|
8
9
|
const OPERATION = "capture_browser_scenario";
|
|
@@ -22,6 +23,9 @@ export class PlaywrightScenarioBrowserCleanupOwner {
|
|
|
22
23
|
this.resources = resources;
|
|
23
24
|
this.#profileRemoved = resources.removeProfile === undefined;
|
|
24
25
|
}
|
|
26
|
+
get browserClosed() {
|
|
27
|
+
return this.#browserClosed;
|
|
28
|
+
}
|
|
25
29
|
close(finishEvents, signal) {
|
|
26
30
|
const cleanup = this.#closePromise ?? this.#closeResources(finishEvents);
|
|
27
31
|
if (this.#closePromise === undefined) {
|
|
@@ -63,6 +67,9 @@ export class PlaywrightScenarioBrowserCleanupOwner {
|
|
|
63
67
|
await eventFinalization;
|
|
64
68
|
}
|
|
65
69
|
catch (cause) {
|
|
70
|
+
// A failed finalization stays failed: the memoized attempt rejects on
|
|
71
|
+
// every retry so cleanup can never report success for unfinalized
|
|
72
|
+
// events.
|
|
66
73
|
failures.push(cause);
|
|
67
74
|
}
|
|
68
75
|
if (!this.#browserClosed) {
|
|
@@ -119,10 +126,19 @@ const createAttachedScenarioRelease = (key, admission) => {
|
|
|
119
126
|
releaseAttachedScenario(key, admission);
|
|
120
127
|
};
|
|
121
128
|
};
|
|
129
|
+
/** One browser admission. The key is the discovery URL this endpoint already parses. */
|
|
130
|
+
export const attachedScenarioLeaseKey = (endpoint, targetId) => {
|
|
131
|
+
const discovery = new URL("/json/version", endpoint);
|
|
132
|
+
// One CDP browser serves every loopback stack on one port, so spellings that
|
|
133
|
+
// reach it through 127.0.0.1 or ::1 must share a single admission.
|
|
134
|
+
if (isLiteralLoopbackHostname(discovery.hostname))
|
|
135
|
+
discovery.hostname = "127.0.0.1";
|
|
136
|
+
return JSON.stringify([discovery.href, targetId]);
|
|
137
|
+
};
|
|
122
138
|
const acquireAttachedScenario = (scenario, signal) => {
|
|
123
139
|
if (signal?.aborted === true)
|
|
124
140
|
return Promise.reject(new BrowserObservationError(OPERATION, "cancelled"));
|
|
125
|
-
const key =
|
|
141
|
+
const key = attachedScenarioLeaseKey(scenario.cdp_endpoint, scenario.target_id);
|
|
126
142
|
const admission = attachedScenarioAdmissions.get(key) ??
|
|
127
143
|
{
|
|
128
144
|
active: false,
|
|
@@ -180,9 +196,23 @@ const allowedBrowserEnvironment = (environment) => {
|
|
|
180
196
|
"XAUTHORITY",
|
|
181
197
|
"XDG_RUNTIME_DIR",
|
|
182
198
|
];
|
|
183
|
-
|
|
199
|
+
const selected = Object.fromEntries(allowed
|
|
184
200
|
.map((name) => [name, environment[name]])
|
|
185
201
|
.filter((entry) => entry[1] !== undefined));
|
|
202
|
+
if (process.platform !== "android")
|
|
203
|
+
return selected;
|
|
204
|
+
// Android rejects execve() for binaries below Termux's application data
|
|
205
|
+
// directory. Termux supplies an exec interceptor that rewrites those calls
|
|
206
|
+
// through the system linker and removes itself for the launched program.
|
|
207
|
+
// Playwright must retain it for its Chromium child process.
|
|
208
|
+
const prefix = environment.PREFIX;
|
|
209
|
+
if (prefix === undefined)
|
|
210
|
+
return selected;
|
|
211
|
+
return {
|
|
212
|
+
...selected,
|
|
213
|
+
LD_PRELOAD: `${prefix}/lib/libtermux-exec.so`,
|
|
214
|
+
TERMUX_EXEC__PROC_SELF_EXE: process.execPath,
|
|
215
|
+
};
|
|
186
216
|
};
|
|
187
217
|
const findConnectedPage = async (browser, targetId, signal) => {
|
|
188
218
|
for (const context of browser.contexts())
|
|
@@ -254,7 +284,7 @@ export const failBrowserScenarioOperation = async (cleanup, primaryFailure, fall
|
|
|
254
284
|
}
|
|
255
285
|
throw primaryFailure;
|
|
256
286
|
};
|
|
257
|
-
const openAttachedScenarioBrowser = async (browserRequest, environment, launcher, signal) => {
|
|
287
|
+
const openAttachedScenarioBrowser = async (browserRequest, environment, launcher, signal, retainCleanup) => {
|
|
258
288
|
const lease = await acquireAttachedScenario(browserRequest, signal);
|
|
259
289
|
let cleanupOwner;
|
|
260
290
|
try {
|
|
@@ -291,14 +321,22 @@ const openAttachedScenarioBrowser = async (browserRequest, environment, launcher
|
|
|
291
321
|
throw cause;
|
|
292
322
|
}
|
|
293
323
|
const cleanup = cleanupOwner;
|
|
294
|
-
|
|
324
|
+
const close = () => cleanup.close();
|
|
325
|
+
try {
|
|
326
|
+
return await failBrowserScenarioOperation(close, cause);
|
|
327
|
+
}
|
|
328
|
+
catch (failure) {
|
|
329
|
+
if (failure !== cause)
|
|
330
|
+
retainCleanup?.(close);
|
|
331
|
+
throw failure;
|
|
332
|
+
}
|
|
295
333
|
}
|
|
296
334
|
};
|
|
297
335
|
/** Launch or attach using the caller-selected environment and browser engine. */
|
|
298
336
|
export const openPlaywrightScenarioBrowser = async (scenario, environment, options = {}) => {
|
|
299
337
|
const launcher = options.launcher ?? chromium;
|
|
300
338
|
if (scenario.browser.mode === "connect")
|
|
301
|
-
return openAttachedScenarioBrowser(scenario.browser, scenario.environment, launcher, options.signal);
|
|
339
|
+
return openAttachedScenarioBrowser(scenario.browser, scenario.environment, launcher, options.signal, options.retainCleanup);
|
|
302
340
|
const profilePath = await mkdtemp(join(tmpdir(), "rea-browser-scenario-"));
|
|
303
341
|
let context;
|
|
304
342
|
try {
|
|
@@ -322,10 +360,26 @@ export const openPlaywrightScenarioBrowser = async (scenario, environment, optio
|
|
|
322
360
|
handleSIGINT: false,
|
|
323
361
|
handleSIGTERM: false,
|
|
324
362
|
timeout: 0,
|
|
363
|
+
// Termux's Chromium cannot create its renderer process through Android's
|
|
364
|
+
// executable boundary. Single-process mode keeps the browser and page in
|
|
365
|
+
// the Termux-launched process so scenario navigation remains available.
|
|
366
|
+
args: process.platform === "android"
|
|
367
|
+
? ["--no-sandbox", "--single-process"]
|
|
368
|
+
: [],
|
|
325
369
|
});
|
|
326
370
|
}
|
|
327
371
|
catch (cause) {
|
|
328
|
-
|
|
372
|
+
const cleanup = () => rm(profilePath, { recursive: true, force: true, maxRetries: 3 });
|
|
373
|
+
try {
|
|
374
|
+
return await failBrowserScenarioOperation(cleanup, cause, [
|
|
375
|
+
"browser_profile",
|
|
376
|
+
]);
|
|
377
|
+
}
|
|
378
|
+
catch (failure) {
|
|
379
|
+
if (failure !== cause)
|
|
380
|
+
options.retainCleanup?.(cleanup);
|
|
381
|
+
throw failure;
|
|
382
|
+
}
|
|
329
383
|
}
|
|
330
384
|
const cleanup = new PlaywrightScenarioBrowserCleanupOwner({
|
|
331
385
|
closeBrowser: () => context.close(),
|
|
@@ -345,6 +399,14 @@ export const openPlaywrightScenarioBrowser = async (scenario, environment, optio
|
|
|
345
399
|
};
|
|
346
400
|
}
|
|
347
401
|
catch (cause) {
|
|
348
|
-
|
|
402
|
+
const close = () => cleanup.close();
|
|
403
|
+
try {
|
|
404
|
+
return await failBrowserScenarioOperation(close, cause);
|
|
405
|
+
}
|
|
406
|
+
catch (failure) {
|
|
407
|
+
if (failure !== cause)
|
|
408
|
+
options.retainCleanup?.(close);
|
|
409
|
+
throw failure;
|
|
410
|
+
}
|
|
349
411
|
}
|
|
350
412
|
};
|