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,32 +1,65 @@
|
|
|
1
1
|
import { lstat } from "node:fs/promises";
|
|
2
|
+
import { readFileHandleChunks } from "../../filesystem/readFileHandleChunks.js";
|
|
3
|
+
import { OwnedFileHandle } from "../../filesystem/OwnedFileHandle.js";
|
|
2
4
|
import { ArtifactReaderFailure } from "../ArtifactReader.js";
|
|
3
|
-
import { NonRegularFileReadError, openRegularFile, sameRegularFileState, } from "../../filesystem/RegularFile.js";
|
|
5
|
+
import { NonRegularFileReadError, RegularFileAdmissionFailure, openRegularFile, sameRegularFileState, } from "../../filesystem/RegularFile.js";
|
|
4
6
|
import { abortIfNeeded, hashReadable, } from "../ArtifactHash.js";
|
|
5
|
-
/**
|
|
6
|
-
export const
|
|
7
|
-
let handle;
|
|
7
|
+
/** Admit a root descriptor without losing ownership when validation cleanup fails. */
|
|
8
|
+
export const openRootArtifact = async (path, resourceScope, signal) => {
|
|
8
9
|
try {
|
|
9
|
-
|
|
10
|
-
symlinks: "reject",
|
|
11
|
-
signal,
|
|
12
|
-
});
|
|
10
|
+
return new OwnedFileHandle(await openRegularFile(path, { symlinks: "reject", signal }));
|
|
13
11
|
}
|
|
14
12
|
catch (cause) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
const primary = cause instanceof RegularFileAdmissionFailure ? cause.cause : cause;
|
|
14
|
+
const failure = primary instanceof NonRegularFileReadError
|
|
15
|
+
? new ArtifactReaderFailure("format", `Artifact root is not a regular file: ${path}`, { cause: primary })
|
|
16
|
+
: primary;
|
|
17
|
+
if (cause instanceof RegularFileAdmissionFailure) {
|
|
18
|
+
const resource = `root artifact descriptor for ${path}`;
|
|
19
|
+
const cleanup = await resourceScope.release({
|
|
20
|
+
kind: "file-handle",
|
|
21
|
+
resource,
|
|
22
|
+
handle: cause.owner,
|
|
23
|
+
});
|
|
24
|
+
if (cleanup.kind === "failed")
|
|
25
|
+
throw ArtifactReaderFailure.withCleanup(failure, ArtifactReaderFailure.cleanupObservation(cleanup.cause, resource));
|
|
26
|
+
}
|
|
27
|
+
throw failure;
|
|
18
28
|
}
|
|
29
|
+
};
|
|
30
|
+
/** Hash one stable regular root file from the same descriptor that was checked. */
|
|
31
|
+
export const hashStableRootArtifact = async (path, resourceScope, signal) => {
|
|
32
|
+
const owner = await openRootArtifact(path, resourceScope, signal);
|
|
33
|
+
const handle = owner.handle;
|
|
34
|
+
let outcome;
|
|
19
35
|
try {
|
|
20
36
|
const initial = await handle.stat();
|
|
21
|
-
|
|
37
|
+
outcome = {
|
|
38
|
+
kind: "completed",
|
|
39
|
+
value: await hashStableRootArtifactHandle(path, handle, initial, signal),
|
|
40
|
+
};
|
|
22
41
|
}
|
|
23
|
-
|
|
24
|
-
|
|
42
|
+
catch (cause) {
|
|
43
|
+
outcome = { kind: "failed", cause };
|
|
25
44
|
}
|
|
45
|
+
const resource = `root artifact descriptor for ${path}`;
|
|
46
|
+
const cleanup = await resourceScope.release({
|
|
47
|
+
kind: "file-handle",
|
|
48
|
+
resource,
|
|
49
|
+
handle: owner,
|
|
50
|
+
});
|
|
51
|
+
if (cleanup.kind === "failed")
|
|
52
|
+
throw ArtifactReaderFailure.withCleanup(outcome.kind === "failed" ? outcome.cause : cleanup.cause, ArtifactReaderFailure.cleanupObservation(cleanup.cause, resource));
|
|
53
|
+
if (outcome.kind === "failed")
|
|
54
|
+
throw outcome.cause;
|
|
55
|
+
return outcome.value;
|
|
26
56
|
};
|
|
27
57
|
/** Hash and revalidate the same open descriptor used for root classification. */
|
|
28
58
|
export const hashStableRootArtifactHandle = async (path, handle, initial, signal) => {
|
|
29
|
-
const digest = await hashReadable(
|
|
59
|
+
const digest = await hashReadable(
|
|
60
|
+
// Read at most the admitted extent plus one byte to detect growth without
|
|
61
|
+
// following an actively appended file indefinitely.
|
|
62
|
+
readFileHandleChunks(handle, { start: 0, end: initial.size }), signal);
|
|
30
63
|
abortIfNeeded(signal);
|
|
31
64
|
const [opened, currentPath] = await Promise.all([handle.stat(), lstat(path)]);
|
|
32
65
|
if (!sameRegularFileState(initial, opened) ||
|
|
@@ -3,7 +3,8 @@ import { DirectoryArtifactReader } from "../DirectoryArtifactReader.js";
|
|
|
3
3
|
import { MachOSliceArtifactReader } from "../MachOSliceArtifactReader.js";
|
|
4
4
|
import { NativeDmgArtifactReader } from "../NativeDmgArtifactReader.js";
|
|
5
5
|
import { ZipArtifactReader } from "../ZipArtifactReader.js";
|
|
6
|
-
|
|
6
|
+
import { ZIP_NON_ENTRY_TAIL_LIMITATION } from "../../domain/zipPackageFormat.js";
|
|
7
|
+
export const createReader = (path, format, environment, rootSource) => {
|
|
7
8
|
switch (format) {
|
|
8
9
|
case "directory":
|
|
9
10
|
return new DirectoryArtifactReader(path);
|
|
@@ -12,24 +13,31 @@ export const createReader = async (path, format, environment, signal) => {
|
|
|
12
13
|
case "apk":
|
|
13
14
|
case "msix":
|
|
14
15
|
case "appx":
|
|
15
|
-
return new ZipArtifactReader(path, format);
|
|
16
|
+
return new ZipArtifactReader(path, format, undefined, rootSource);
|
|
16
17
|
case "asar":
|
|
17
18
|
return new AsarArtifactReader(path);
|
|
18
19
|
case "mach-o-universal":
|
|
19
20
|
return process.platform === "darwin"
|
|
20
|
-
? new MachOSliceArtifactReader(path, environment)
|
|
21
|
+
? new MachOSliceArtifactReader(path, environment, undefined, rootSource)
|
|
21
22
|
: undefined;
|
|
22
23
|
case "dmg":
|
|
23
24
|
if (process.platform !== "darwin")
|
|
24
25
|
return undefined;
|
|
25
|
-
return NativeDmgArtifactReader
|
|
26
|
+
return new NativeDmgArtifactReader(path, environment);
|
|
26
27
|
default:
|
|
27
28
|
return undefined;
|
|
28
29
|
}
|
|
29
30
|
};
|
|
30
31
|
export const inventoryLimitations = (format, reader) => {
|
|
31
32
|
if (reader !== undefined)
|
|
32
|
-
return
|
|
33
|
+
return reader.format === "zip" ||
|
|
34
|
+
reader.format === "ipa" ||
|
|
35
|
+
reader.format === "apk" ||
|
|
36
|
+
reader.format === "msix" ||
|
|
37
|
+
reader.format === "appx"
|
|
38
|
+
? [ZIP_NON_ENTRY_TAIL_LIMITATION]
|
|
39
|
+
: [];
|
|
40
|
+
// dmg and pkg reach here only after classifyRootFormat matched their bytes.
|
|
33
41
|
if (format === "dmg" || format === "pkg")
|
|
34
42
|
return [
|
|
35
43
|
`${format.toUpperCase()} root hash is observed; child inventory requires a native macOS adapter.`,
|
|
@@ -5,23 +5,33 @@ import { ArtifactReaderFailure, } from "../ArtifactReader.js";
|
|
|
5
5
|
import { artifactInventoryResultSchema, } from "../../domain/artifactGraph.js";
|
|
6
6
|
import { createArtifactEdges, createRootNode, indexOccurrencesByPath, materializeDirectoryNodes, rekeyOccurrences, rootOccurrenceFor, } from "./ArtifactGraphConstruction.js";
|
|
7
7
|
import { artifactContradictionId, artifactGraphDigest, artifactManifestId, } from "../../domain/artifactIdentity.js";
|
|
8
|
-
import {
|
|
8
|
+
import { classifyAndHashRootForInventory } from "./classify.js";
|
|
9
9
|
import {} from "../ArtifactHash.js";
|
|
10
|
-
import { hashStableRootArtifact } from "./hashStableRootArtifact.js";
|
|
10
|
+
import { hashStableRootArtifact, hashStableRootArtifactHandle, } from "./hashStableRootArtifact.js";
|
|
11
11
|
import { createReader, inventoryLimitations } from "./reader.js";
|
|
12
12
|
import { scanReader, } from "./scanReader.js";
|
|
13
13
|
import { STRICT_INTEGRITY_POLICY, } from "./types.js";
|
|
14
|
-
export const scanCanonicalArtifactInventory = async (path, options
|
|
14
|
+
export const scanCanonicalArtifactInventory = async (path, options, readerFactory = createReader) => options.resourceScope.run(() => scanCanonicalArtifactInventoryInScope(path, options, readerFactory));
|
|
15
|
+
export const scanCanonicalArtifactInventoryInScope = async (path, options, readerFactory = createReader) => {
|
|
15
16
|
const integrity = options.integrity ?? STRICT_INTEGRITY_POLICY;
|
|
16
17
|
const metadata = await lstat(path);
|
|
17
|
-
const { format: rootFormat, digest: rootDigest } = await
|
|
18
|
-
|
|
18
|
+
const { format: rootFormat, digest: rootDigest, rootSource, } = await classifyAndHashRootForInventory(path, metadata.isDirectory(), metadata, options);
|
|
19
|
+
let reader;
|
|
20
|
+
let readerCreationFailure;
|
|
21
|
+
try {
|
|
22
|
+
reader = readerFactory(path, rootFormat, options.environment ?? {}, rootSource);
|
|
23
|
+
}
|
|
24
|
+
catch (cause) {
|
|
25
|
+
readerCreationFailure = { cause };
|
|
26
|
+
}
|
|
19
27
|
const ownedReaders = reader === undefined ? [] : [reader];
|
|
20
28
|
let outcome;
|
|
21
29
|
try {
|
|
30
|
+
if (readerCreationFailure !== undefined)
|
|
31
|
+
throw readerCreationFailure.cause;
|
|
22
32
|
if (reader instanceof AsarArtifactReader)
|
|
23
33
|
await reader.prepareContainer(rootDigest?.sha256, options.signal);
|
|
24
|
-
const { nodes, occurrences, pendingContradictions } = await scanReader(reader, ownedReaders, options.signal, integrity);
|
|
34
|
+
const { nodes, occurrences, pendingContradictions, caseCollisionLimitation, } = await scanReader(reader, ownedReaders, options.signal, integrity);
|
|
25
35
|
outcome = {
|
|
26
36
|
kind: "completed",
|
|
27
37
|
snapshot: await buildInventorySnapshot({
|
|
@@ -29,38 +39,62 @@ export const scanCanonicalArtifactInventory = async (path, options = {}, readerF
|
|
|
29
39
|
metadata,
|
|
30
40
|
rootFormat,
|
|
31
41
|
rootDigest,
|
|
42
|
+
rootSource,
|
|
43
|
+
resourceScope: options.resourceScope,
|
|
32
44
|
reader,
|
|
33
45
|
signal: options.signal,
|
|
34
46
|
nodes,
|
|
35
47
|
occurrences,
|
|
36
48
|
pendingContradictions,
|
|
49
|
+
caseCollisionLimitation,
|
|
37
50
|
}),
|
|
38
51
|
};
|
|
39
52
|
}
|
|
40
53
|
catch (cause) {
|
|
41
54
|
outcome = { kind: "failed", cause };
|
|
42
55
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
cleanupFailure = ArtifactReaderFailure.withCleanup(cleanupFailure ??
|
|
51
|
-
(outcome.kind === "failed" ? outcome.cause : cleanupCause), cleanup, outcome.kind === "completed"
|
|
52
|
-
? { kind: "artifact-inventory", inventory: outcome.snapshot }
|
|
53
|
-
: undefined);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
+
const cleanupFailure = await cleanupInventoryOwners({
|
|
57
|
+
path,
|
|
58
|
+
options,
|
|
59
|
+
rootSource,
|
|
60
|
+
ownedReaders,
|
|
61
|
+
outcome,
|
|
62
|
+
});
|
|
56
63
|
if (cleanupFailure !== undefined)
|
|
57
64
|
throw cleanupFailure;
|
|
58
65
|
if (outcome.kind === "failed")
|
|
59
66
|
throw outcome.cause;
|
|
60
67
|
return outcome.snapshot;
|
|
61
68
|
};
|
|
69
|
+
const cleanupInventoryOwners = async ({ path, options, rootSource, ownedReaders, outcome, }) => {
|
|
70
|
+
let cleanupFailure;
|
|
71
|
+
const owners = [...ownedReaders]
|
|
72
|
+
.reverse()
|
|
73
|
+
.map((reader) => ({
|
|
74
|
+
kind: "reader",
|
|
75
|
+
reader,
|
|
76
|
+
resource: `artifact reader for ${path}`,
|
|
77
|
+
}));
|
|
78
|
+
if (rootSource !== undefined)
|
|
79
|
+
owners.push({
|
|
80
|
+
kind: "file-handle",
|
|
81
|
+
handle: rootSource.owner,
|
|
82
|
+
resource: `root artifact descriptor for ${path}`,
|
|
83
|
+
});
|
|
84
|
+
for (const owner of owners) {
|
|
85
|
+
const attempt = await options.resourceScope.release(owner);
|
|
86
|
+
if (attempt.kind === "released")
|
|
87
|
+
continue;
|
|
88
|
+
const primary = cleanupFailure ??
|
|
89
|
+
(outcome.kind === "failed" ? outcome.cause : attempt.cause);
|
|
90
|
+
cleanupFailure = ArtifactReaderFailure.withCleanup(primary, ArtifactReaderFailure.cleanupObservation(attempt.cause, owner.resource), outcome.kind === "completed"
|
|
91
|
+
? { kind: "artifact-inventory", inventory: outcome.snapshot }
|
|
92
|
+
: undefined);
|
|
93
|
+
}
|
|
94
|
+
return cleanupFailure;
|
|
95
|
+
};
|
|
62
96
|
const buildInventorySnapshot = async (input) => {
|
|
63
|
-
const { path, metadata, rootFormat, rootDigest, reader, signal } = input;
|
|
97
|
+
const { path, metadata, rootFormat, rootDigest, rootSource, reader, signal } = input;
|
|
64
98
|
materializeDirectoryNodes(input.occurrences, input.nodes);
|
|
65
99
|
const rootNode = createRootNode({
|
|
66
100
|
digest: rootDigest,
|
|
@@ -91,7 +125,7 @@ const buildInventorySnapshot = async (input) => {
|
|
|
91
125
|
...edge,
|
|
92
126
|
ordinal,
|
|
93
127
|
}));
|
|
94
|
-
await verifyRootDigest(path, rootDigest, signal);
|
|
128
|
+
await verifyRootDigest(path, rootDigest, rootSource, input.resourceScope, signal);
|
|
95
129
|
const graphSha256 = artifactGraphDigest({
|
|
96
130
|
nodes: orderedNodes,
|
|
97
131
|
occurrences: orderedOccurrences,
|
|
@@ -113,7 +147,7 @@ const buildInventorySnapshot = async (input) => {
|
|
|
113
147
|
edges: orderedEdges,
|
|
114
148
|
provenance: reader?.provenance() ?? [],
|
|
115
149
|
integrity_contradictions: integrityContradictions,
|
|
116
|
-
limitations: buildLimitations(rootFormat, reader, integrityContradictions),
|
|
150
|
+
limitations: buildLimitations(rootFormat, reader, integrityContradictions, input.caseCollisionLimitation),
|
|
117
151
|
};
|
|
118
152
|
};
|
|
119
153
|
const buildIntegrityContradictions = (pending, occurrenceByPath, occurrenceById, rootNode) => pending.map((contradiction) => {
|
|
@@ -145,10 +179,12 @@ const buildIntegrityContradictions = (pending, occurrenceByPath, occurrenceById,
|
|
|
145
179
|
],
|
|
146
180
|
};
|
|
147
181
|
});
|
|
148
|
-
const verifyRootDigest = async (path, rootDigest, signal) => {
|
|
182
|
+
const verifyRootDigest = async (path, rootDigest, rootSource, resourceScope, signal) => {
|
|
149
183
|
if (rootDigest === null)
|
|
150
184
|
return;
|
|
151
|
-
const verified =
|
|
185
|
+
const verified = rootSource === undefined
|
|
186
|
+
? await hashStableRootArtifact(path, resourceScope, signal)
|
|
187
|
+
: await hashStableRootArtifactHandle(path, rootSource.handle, rootSource.initial, signal);
|
|
152
188
|
if (verified.sha256 !== rootDigest.sha256 ||
|
|
153
189
|
verified.bytes !== rootDigest.bytes)
|
|
154
190
|
throw new ArtifactReaderFailure("integrity", "Root artifact changed during inventory");
|
|
@@ -166,8 +202,9 @@ const buildManifest = ({ rootNode, rootFormat, graphSha256, orderedNodes, ordere
|
|
|
166
202
|
occurrence_count: orderedOccurrences.length,
|
|
167
203
|
edge_count: orderedEdges.length,
|
|
168
204
|
});
|
|
169
|
-
const buildLimitations = (rootFormat, reader, integrityContradictions) => [
|
|
205
|
+
const buildLimitations = (rootFormat, reader, integrityContradictions, caseCollisionLimitation) => [
|
|
170
206
|
...inventoryLimitations(rootFormat, reader),
|
|
207
|
+
...(caseCollisionLimitation === undefined ? [] : [caseCollisionLimitation]),
|
|
171
208
|
...(integrityContradictions.length === 0
|
|
172
209
|
? []
|
|
173
210
|
: [
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { isAbsolute } from "node:path";
|
|
2
|
-
import { ArtifactPathRegistry, normalizeArtifactPath, } from "../ArtifactPaths.js";
|
|
2
|
+
import { annotateEnglishUnicodeCaseCollisions, ArtifactPathRegistry, normalizeArtifactPath, } from "../ArtifactPaths.js";
|
|
3
3
|
import { ArtifactReaderFailure, } from "../ArtifactReader.js";
|
|
4
4
|
import { AsarArtifactReader } from "../AsarArtifactReader.js";
|
|
5
|
-
import { classifyArtifactContent, classifyArtifactBytes, createArtifactNode, createOccurrence,
|
|
5
|
+
import { classifyArtifactContent, classifyArtifactBytes, createArtifactNode, createOccurrence, noteUnreadContainerSuffix, resolveOccurrenceParents, } from "./ArtifactGraphConstruction.js";
|
|
6
6
|
import { STRICT_INTEGRITY_POLICY, } from "./types.js";
|
|
7
7
|
import { hashReadable } from "../ArtifactHash.js";
|
|
8
8
|
const UNAVAILABLE_UNPACKED_LIMITATION = "ASAR unpacked companion bytes were unavailable; no content hash or child artifact was produced.";
|
|
@@ -10,7 +10,12 @@ const emptyScan = () => ({ nodes: new Map(), occurrences: [], pendingContradicti
|
|
|
10
10
|
export const scanReader = async (reader, ownedReaders, signal, integrity = STRICT_INTEGRITY_POLICY) => {
|
|
11
11
|
const { nodes, occurrences, pendingContradictions } = emptyScan();
|
|
12
12
|
if (reader === undefined)
|
|
13
|
-
return {
|
|
13
|
+
return {
|
|
14
|
+
nodes,
|
|
15
|
+
occurrences,
|
|
16
|
+
pendingContradictions,
|
|
17
|
+
caseCollisionLimitation: undefined,
|
|
18
|
+
};
|
|
14
19
|
const context = {
|
|
15
20
|
reader,
|
|
16
21
|
signal,
|
|
@@ -26,10 +31,13 @@ export const scanReader = async (reader, ownedReaders, signal, integrity = STRIC
|
|
|
26
31
|
await visitArtifactEntries(context, reader, "");
|
|
27
32
|
// Archive directories may appear after their children. Resolve containment
|
|
28
33
|
// against the complete index before directory identities are materialized.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
resolveOccurrenceParents(occurrences, context.occurrenceByPath, context.expandedContainerIds);
|
|
35
|
+
return {
|
|
36
|
+
nodes,
|
|
37
|
+
occurrences,
|
|
38
|
+
pendingContradictions,
|
|
39
|
+
caseCollisionLimitation: annotateEnglishUnicodeCaseCollisions(occurrences),
|
|
40
|
+
};
|
|
33
41
|
};
|
|
34
42
|
const visitArtifactEntries = async (context, currentReader, prefix) => {
|
|
35
43
|
const stack = [
|
|
@@ -39,6 +47,7 @@ const visitArtifactEntries = async (context, currentReader, prefix) => {
|
|
|
39
47
|
iterator: currentReader.entries(context.signal)[Symbol.asyncIterator](),
|
|
40
48
|
},
|
|
41
49
|
];
|
|
50
|
+
let failure;
|
|
42
51
|
try {
|
|
43
52
|
while (stack.length > 0) {
|
|
44
53
|
const frame = stack.at(-1);
|
|
@@ -66,7 +75,9 @@ const visitArtifactEntries = async (context, currentReader, prefix) => {
|
|
|
66
75
|
occurrence.hash_status = "unavailable";
|
|
67
76
|
occurrence.limitations.push(UNAVAILABLE_UNPACKED_LIMITATION);
|
|
68
77
|
}
|
|
69
|
-
if (digested
|
|
78
|
+
if (digested === undefined)
|
|
79
|
+
noteUnreadContainerSuffix(occurrence);
|
|
80
|
+
else {
|
|
70
81
|
context.nodes.set(digested.node.artifact_id, digested.node);
|
|
71
82
|
occurrence.artifact_id = digested.node.artifact_id;
|
|
72
83
|
occurrence.artifact_kind = digested.classification.kind;
|
|
@@ -79,7 +90,10 @@ const visitArtifactEntries = async (context, currentReader, prefix) => {
|
|
|
79
90
|
}
|
|
80
91
|
context.occurrences.push(occurrence);
|
|
81
92
|
context.occurrenceByPath.set(logicalPath, occurrence);
|
|
82
|
-
if (expandableAsar &&
|
|
93
|
+
if (expandableAsar &&
|
|
94
|
+
digested !== undefined &&
|
|
95
|
+
digested.classification.format === "asar" &&
|
|
96
|
+
!digested.mismatched) {
|
|
83
97
|
const nested = new AsarArtifactReader(entry.adapterKey);
|
|
84
98
|
context.ownedReaders.push(nested);
|
|
85
99
|
await nested.prepareContainer(digested.node.sha256, context.signal);
|
|
@@ -93,11 +107,24 @@ const visitArtifactEntries = async (context, currentReader, prefix) => {
|
|
|
93
107
|
}
|
|
94
108
|
}
|
|
95
109
|
}
|
|
110
|
+
catch (cause) {
|
|
111
|
+
failure = { cause };
|
|
112
|
+
}
|
|
96
113
|
finally {
|
|
97
114
|
// Readers remain owned by the inventory until its complete observation is built.
|
|
98
|
-
for (const { iterator } of stack)
|
|
99
|
-
|
|
115
|
+
for (const { iterator, prefix, reader } of stack.reverse()) {
|
|
116
|
+
try {
|
|
117
|
+
await iterator.return?.();
|
|
118
|
+
}
|
|
119
|
+
catch (cause) {
|
|
120
|
+
failure = {
|
|
121
|
+
cause: ArtifactReaderFailure.withCleanup(failure === undefined ? cause : failure.cause, ArtifactReaderFailure.cleanupObservation(cause, `artifact traversal for ${prefix || reader.format}`)),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
100
125
|
}
|
|
126
|
+
if (failure !== undefined)
|
|
127
|
+
throw failure.cause;
|
|
101
128
|
};
|
|
102
129
|
const digestArtifactEntry = async (context, currentReader, entry, logicalPath) => {
|
|
103
130
|
if ((entry.kind !== "file" && entry.kind !== "slice") || entry.encrypted)
|
|
@@ -7,7 +7,7 @@ import { ArtifactReaderFailure, } from "../ArtifactReader.js";
|
|
|
7
7
|
import { streamChunkToBuffer } from "../StreamBytes.js";
|
|
8
8
|
import { hashReadable } from "../ArtifactHash.js";
|
|
9
9
|
/** Read all relevant textual entries through an already-inventoried reader. */
|
|
10
|
-
export const readJavaScriptArtifactFiles = async (reader, snapshot, signal) => {
|
|
10
|
+
export const readJavaScriptArtifactFiles = async (reader, snapshot, resources, signal) => {
|
|
11
11
|
if (reader instanceof AsarArtifactReader) {
|
|
12
12
|
const root = snapshot.nodes.find(({ artifact_id }) => artifact_id === snapshot.manifest.root_artifact_id);
|
|
13
13
|
if (root === undefined)
|
|
@@ -17,6 +17,7 @@ export const readJavaScriptArtifactFiles = async (reader, snapshot, signal) => {
|
|
|
17
17
|
const inventory = expectedInventory(snapshot);
|
|
18
18
|
const expected = inventory.files;
|
|
19
19
|
const context = {
|
|
20
|
+
resources,
|
|
20
21
|
expected,
|
|
21
22
|
expectedContainers: inventory.containers,
|
|
22
23
|
registry: new ArtifactPathRegistry(),
|
|
@@ -81,7 +82,7 @@ const visitReader = async (reader, prefix, containerSha256, context) => {
|
|
|
81
82
|
await verifyEntryBytes(await frame.reader.open(entry, context.signal), inventory, context.signal);
|
|
82
83
|
context.containers.push(inventory);
|
|
83
84
|
const nested = new AsarArtifactReader(entry.adapterKey);
|
|
84
|
-
ownedReaders.push(nested);
|
|
85
|
+
ownedReaders.push({ reader: nested, path });
|
|
85
86
|
stack.push({
|
|
86
87
|
reader: nested,
|
|
87
88
|
prefix: path,
|
|
@@ -115,21 +116,26 @@ const visitReader = async (reader, prefix, containerSha256, context) => {
|
|
|
115
116
|
failure = { cause };
|
|
116
117
|
}
|
|
117
118
|
finally {
|
|
118
|
-
for (const { iterator } of stack) {
|
|
119
|
+
for (const { iterator, prefix, reader } of stack.reverse()) {
|
|
119
120
|
try {
|
|
120
121
|
await iterator.return?.();
|
|
121
122
|
}
|
|
122
123
|
catch (cause) {
|
|
123
|
-
failure
|
|
124
|
+
failure = {
|
|
125
|
+
cause: ArtifactReaderFailure.withCleanup(failure === undefined ? cause : failure.cause, ArtifactReaderFailure.cleanupObservation(cause, `JavaScript artifact traversal for ${prefix || reader.format}`)),
|
|
126
|
+
};
|
|
124
127
|
}
|
|
125
128
|
}
|
|
126
129
|
for (const owned of ownedReaders.reverse()) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
const resource = `nested ASAR reader for ${owned.path}`;
|
|
131
|
+
const cleanup = await context.resources.release({
|
|
132
|
+
kind: "reader",
|
|
133
|
+
reader: owned.reader,
|
|
134
|
+
resource,
|
|
135
|
+
});
|
|
136
|
+
if (cleanup.kind === "failed") {
|
|
131
137
|
failure = {
|
|
132
|
-
cause: ArtifactReaderFailure.withCleanup(failure
|
|
138
|
+
cause: ArtifactReaderFailure.withCleanup(failure === undefined ? cleanup.cause : failure.cause, ArtifactReaderFailure.cleanupObservation(cleanup.cause, resource)),
|
|
133
139
|
};
|
|
134
140
|
}
|
|
135
141
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { JavaScriptAnalysisWorker } from "../../javascript/analysis/JavaScriptAnalysisWorker.js";
|
|
2
|
+
/** Construct the inert artifact analyzer; resources are acquired on the first source. */
|
|
3
|
+
export const createJavaScriptSourceAnalysis = (limits, sourceCount) => new JavaScriptAnalysisWorker(limits, undefined, sourceCount);
|
|
@@ -5,13 +5,19 @@ import { BrowserObservationError } from "../domain/browserObservationError.js";
|
|
|
5
5
|
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
|
6
6
|
import { PLAYWRIGHT_BROWSER_SCENARIO_PROVIDER_IDENTITY } from "./providerIdentities.js";
|
|
7
7
|
const OPERATION = "capture_browser_scenario";
|
|
8
|
-
const browserScenarioLimitations = (session) => [
|
|
8
|
+
const browserScenarioLimitations = (session, scenario) => [
|
|
9
9
|
"Event sequence records provider receipt order; simultaneous browser causality is not inferred.",
|
|
10
10
|
"Network content is retained only when selected; response bytes are browser-decoded, not compressed wire bytes.",
|
|
11
11
|
"Request bytes are limited to what Playwright exposes; not_exposed does not establish body absence or multipart file coverage.",
|
|
12
12
|
"Network content reads settle within 5 seconds each and never wait for unfinished responses or refetch them.",
|
|
13
13
|
"Playwright scenario events do not expose request initiator stacks; receipt order does not prove causality.",
|
|
14
14
|
"Storage values are hashed only after declared-secret redaction.",
|
|
15
|
+
...(scenario.storage.local_storage.length === 0 &&
|
|
16
|
+
scenario.storage.session_storage.length === 0
|
|
17
|
+
? []
|
|
18
|
+
: [
|
|
19
|
+
"Non-cookie storage seeds use CDP pre-script instrumentation; only pauses in the scenario's private seed script are resumed by this observer.",
|
|
20
|
+
]),
|
|
15
21
|
...(session.eventLimitations?.() ?? []),
|
|
16
22
|
...(session.mode === "connect"
|
|
17
23
|
? [
|
|
@@ -40,7 +46,7 @@ export const browserScenarioCaptureData = (input) => ({
|
|
|
40
46
|
steps: [...input.steps],
|
|
41
47
|
events: input.session.events(),
|
|
42
48
|
limitations: [
|
|
43
|
-
...browserScenarioLimitations(input.session),
|
|
49
|
+
...browserScenarioLimitations(input.session, input.scenario),
|
|
44
50
|
...(input.limitations ?? []),
|
|
45
51
|
],
|
|
46
52
|
});
|
|
@@ -6,6 +6,36 @@ const encodedSecretValues = (secret) => new Set([
|
|
|
6
6
|
encodeURIComponent(secret),
|
|
7
7
|
new URLSearchParams([["value", secret]]).toString().slice("value=".length),
|
|
8
8
|
]);
|
|
9
|
+
const secretSpellings = (secret, spellings) => {
|
|
10
|
+
if (secret === "")
|
|
11
|
+
return [];
|
|
12
|
+
if (spellings === "raw")
|
|
13
|
+
return [secret];
|
|
14
|
+
const values = [...encodedSecretValues(secret)];
|
|
15
|
+
if (spellings === "bytes")
|
|
16
|
+
values.push(JSON.stringify(secret).slice(1, -1));
|
|
17
|
+
return [...new Set(values)].filter((value) => value !== "");
|
|
18
|
+
};
|
|
19
|
+
const declaredLiterals = (values, spellings) => [
|
|
20
|
+
...new Set([...values.values()].flatMap((secret) => secretSpellings(secret, spellings))),
|
|
21
|
+
];
|
|
22
|
+
/** Pick a marker that does not itself contain a declared secret spelling. */
|
|
23
|
+
const redactionMarker = (id, literals) => [`${REDACTION_PREFIX}${id}]`, "[REDACTED]", "…", ""].find((candidate) => literals.every((literal) => !candidate.includes(literal))) ?? "";
|
|
24
|
+
const replaceSecretLiterals = (value, values, spellings, literals) => {
|
|
25
|
+
const replacements = [...values]
|
|
26
|
+
.flatMap(([id, secret]) => secretSpellings(secret, spellings).map((text) => ({ id, text })))
|
|
27
|
+
.sort((left, right) => right.text.length - left.text.length ||
|
|
28
|
+
(left.id < right.id ? -1 : left.id > right.id ? 1 : 0));
|
|
29
|
+
let output = value;
|
|
30
|
+
for (const replacement of replacements)
|
|
31
|
+
output = output.replaceAll(replacement.text, redactionMarker(replacement.id, literals));
|
|
32
|
+
return output;
|
|
33
|
+
};
|
|
34
|
+
const secretNeedles = (values, literals) => [...values].flatMap(([id, secret]) => secretSpellings(secret, "bytes").map((text) => ({
|
|
35
|
+
id,
|
|
36
|
+
needle: Buffer.from(text),
|
|
37
|
+
marker: Buffer.from(redactionMarker(id, literals)),
|
|
38
|
+
})));
|
|
9
39
|
/** Resolved secret values kept only for one in-memory scenario session. */
|
|
10
40
|
export class BrowserScenarioSecrets {
|
|
11
41
|
values;
|
|
@@ -38,35 +68,18 @@ export class BrowserScenarioSecrets {
|
|
|
38
68
|
return url.href;
|
|
39
69
|
}
|
|
40
70
|
redact(value) {
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
for (const [id, secret] of replacements)
|
|
45
|
-
if (secret !== "")
|
|
46
|
-
output = output.replaceAll(secret, `${REDACTION_PREFIX}${id}]`);
|
|
47
|
-
return output;
|
|
71
|
+
const literals = declaredLiterals(this.values, "raw");
|
|
72
|
+
const output = replaceSecretLiterals(value, this.values, "raw", literals);
|
|
73
|
+
return literals.some((literal) => output.includes(literal)) ? "" : output;
|
|
48
74
|
}
|
|
49
75
|
/** Replace declared UTF-8, URI/form, and JSON-escaped secrets without decoding binary data. */
|
|
50
76
|
redactBytes(value) {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
...encodedSecretValues(secret),
|
|
58
|
-
JSON.stringify(secret).slice(1, -1),
|
|
59
|
-
]),
|
|
60
|
-
].map((text) => {
|
|
61
|
-
const needle = Buffer.from(text);
|
|
62
|
-
return {
|
|
63
|
-
id,
|
|
64
|
-
needle,
|
|
65
|
-
marker: Buffer.from(`${REDACTION_PREFIX}${id}]`),
|
|
66
|
-
index: value.indexOf(needle),
|
|
67
|
-
};
|
|
68
|
-
});
|
|
69
|
-
})
|
|
77
|
+
const literals = declaredLiterals(this.values, "bytes");
|
|
78
|
+
const candidates = secretNeedles(this.values, literals)
|
|
79
|
+
.map((candidate) => ({
|
|
80
|
+
...candidate,
|
|
81
|
+
index: value.indexOf(candidate.needle),
|
|
82
|
+
}))
|
|
70
83
|
.sort((left, right) => right.needle.length - left.needle.length ||
|
|
71
84
|
(left.id < right.id ? -1 : left.id > right.id ? 1 : 0));
|
|
72
85
|
const parts = [];
|
|
@@ -88,20 +101,22 @@ export class BrowserScenarioSecrets {
|
|
|
88
101
|
if (parts.length === 0)
|
|
89
102
|
return value;
|
|
90
103
|
parts.push(value.subarray(offset));
|
|
91
|
-
|
|
104
|
+
const redacted = Buffer.concat(parts);
|
|
105
|
+
return literals.some((literal) => redacted.includes(Buffer.from(literal)))
|
|
106
|
+
? Buffer.alloc(0)
|
|
107
|
+
: redacted;
|
|
92
108
|
}
|
|
93
109
|
/** Remove only declared secret values from one URL and report that action. */
|
|
94
110
|
sanitizeUrl(value) {
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
111
|
+
const literals = declaredLiterals(this.values, "url");
|
|
112
|
+
const output = replaceSecretLiterals(value, this.values, "url", literals);
|
|
113
|
+
if (literals.some((literal) => output.includes(literal)))
|
|
114
|
+
return {
|
|
115
|
+
url: "",
|
|
116
|
+
origin: null,
|
|
117
|
+
query_parameter_names: [],
|
|
118
|
+
redacted: true,
|
|
119
|
+
};
|
|
105
120
|
const sanitized = sanitizeBrowserUrl(output);
|
|
106
121
|
return {
|
|
107
122
|
...sanitized,
|
|
@@ -7,6 +7,7 @@ import { webMcpDiscoverySchema, } from "../domain/webMcpDiscovery.js";
|
|
|
7
7
|
import { browserCaptureComparisonSchema, compareBrowserCaptures, } from "../domain/browserCaptureComparison.js";
|
|
8
8
|
import { webScreenshotDiffSchema, webScreenshotSchema, } from "../domain/webScreenshot.js";
|
|
9
9
|
import { AnalysisError } from "../domain/analysisErrorBase.js";
|
|
10
|
+
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
|
|
10
11
|
import { BrowserObservationError } from "../domain/browserObservationError.js";
|
|
11
12
|
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
|
12
13
|
import {} from "../domain/browserObservationErrors.js";
|
|
@@ -173,6 +174,10 @@ export class CdpBrowserProvider {
|
|
|
173
174
|
return ok(webScreenshotDiffSchema.parse(comparePngScreenshots(input)));
|
|
174
175
|
}
|
|
175
176
|
catch (cause) {
|
|
177
|
+
if (cause instanceof TypeError)
|
|
178
|
+
return err(new AnalysisInputError("compare_web_screenshots", { cause }, [
|
|
179
|
+
{ path: [], reason: "invalid_format", message: cause.message },
|
|
180
|
+
]));
|
|
176
181
|
return err(providerError(cause, "compare_web_screenshots"));
|
|
177
182
|
}
|
|
178
183
|
}
|