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
|
@@ -8,6 +8,7 @@ import { err, ok } from "../../domain/result.js";
|
|
|
8
8
|
export const traceNativeValues = async (analysis, parameters, signal) => {
|
|
9
9
|
const input = nativeValueTraceInputSchema.parse(parameters);
|
|
10
10
|
const nodes = [];
|
|
11
|
+
const nodeIds = new Set();
|
|
11
12
|
const edges = [];
|
|
12
13
|
const procedures = [];
|
|
13
14
|
const unknowns = [];
|
|
@@ -116,24 +117,27 @@ export const traceNativeValues = async (analysis, parameters, signal) => {
|
|
|
116
117
|
bytes += size;
|
|
117
118
|
ids.add(operation.id);
|
|
118
119
|
nodes.push(node);
|
|
120
|
+
nodeIds.add(node.id);
|
|
119
121
|
}
|
|
120
122
|
for (const parameter of flow.parameters) {
|
|
121
123
|
if (nodes.length >= input.max_nodes) {
|
|
122
124
|
truncated = true;
|
|
123
125
|
break;
|
|
124
126
|
}
|
|
127
|
+
const id = `${address}/parameter:${parameter.ordinal}`;
|
|
125
128
|
nodes.push({
|
|
126
|
-
id
|
|
129
|
+
id,
|
|
127
130
|
procedure: address,
|
|
128
131
|
evidence_id: evidenceId,
|
|
129
132
|
kind: "parameter",
|
|
130
133
|
operation: null,
|
|
131
134
|
parameter,
|
|
132
135
|
});
|
|
136
|
+
nodeIds.add(id);
|
|
133
137
|
}
|
|
134
138
|
for (const use of flow.parameter_uses) {
|
|
135
139
|
if (!ids.has(use.use) ||
|
|
136
|
-
!
|
|
140
|
+
!nodeIds.has(`${address}/parameter:${use.ordinal}`))
|
|
137
141
|
continue;
|
|
138
142
|
if (edges.length >= input.max_edges) {
|
|
139
143
|
truncated = true;
|
|
@@ -243,8 +247,23 @@ export const traceNativeValues = async (analysis, parameters, signal) => {
|
|
|
243
247
|
}
|
|
244
248
|
if (targetSha256 === undefined)
|
|
245
249
|
return err(new AnalysisOutputError("trace_native_values", "No seed function could be analyzed"));
|
|
250
|
+
const parametersByProcedure = new Map();
|
|
251
|
+
const returnsByProcedure = new Map();
|
|
252
|
+
for (const node of nodes) {
|
|
253
|
+
if (node.kind === "parameter") {
|
|
254
|
+
const parameters = parametersByProcedure.get(node.procedure) ?? [];
|
|
255
|
+
parameters.push(node);
|
|
256
|
+
parametersByProcedure.set(node.procedure, parameters);
|
|
257
|
+
}
|
|
258
|
+
else if (node.operation?.opcode === "RETURN" &&
|
|
259
|
+
node.operation.inputs.length > 1) {
|
|
260
|
+
const returns = returnsByProcedure.get(node.procedure) ?? [];
|
|
261
|
+
returns.push(node);
|
|
262
|
+
returnsByProcedure.set(node.procedure, returns);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
246
265
|
for (const binding of callBindings) {
|
|
247
|
-
const parameters =
|
|
266
|
+
const parameters = parametersByProcedure.get(binding.callee) ?? [];
|
|
248
267
|
if (parameters.length === 0)
|
|
249
268
|
unknowns.push({
|
|
250
269
|
procedure: binding.caller,
|
|
@@ -275,9 +294,7 @@ export const traceNativeValues = async (analysis, parameters, signal) => {
|
|
|
275
294
|
});
|
|
276
295
|
}
|
|
277
296
|
if (binding.output)
|
|
278
|
-
for (const node of
|
|
279
|
-
node.operation?.opcode === "RETURN" &&
|
|
280
|
-
node.operation.inputs.length > 1)) {
|
|
297
|
+
for (const node of returnsByProcedure.get(binding.callee) ?? []) {
|
|
281
298
|
if (edges.length >= input.max_edges) {
|
|
282
299
|
truncated = true;
|
|
283
300
|
break;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
1
|
import { z } from "zod";
|
|
3
2
|
import { AnalysisError } from "../../domain/analysisErrorBase.js";
|
|
4
3
|
import { AnalysisInputError } from "../../domain/analysisErrorCore.js";
|
|
@@ -11,9 +10,12 @@ import { processTraceSpecificationSchema } from "../../domain/process/processTra
|
|
|
11
10
|
import { processScenarioSchema } from "../../domain/process/processScenario.js";
|
|
12
11
|
import { compareProcessCaptures } from "../../domain/process/processComparison.js";
|
|
13
12
|
import { parseProcessCapture } from "../../domain/process/processCaptureParsing.js";
|
|
13
|
+
import { createProgressReporter } from "../ProgressReporter.js";
|
|
14
14
|
import { captureProcessScenario } from "../../process/capture/ProcessHarness.js";
|
|
15
|
+
import { ProcessCaptureResourceScope } from "../../process/capture/ProcessCaptureLifecycle.js";
|
|
15
16
|
import { PROCESS_PROVIDER } from "../../domain/process/processEvidenceProvider.js";
|
|
16
17
|
import { createProcessCaptureEvidence } from "./ProcessEvidence.js";
|
|
18
|
+
import { readJsonFile } from "../JsonFiles.js";
|
|
17
19
|
/** Identify the process workflow's typed diagnostic result for CLI exit status. */
|
|
18
20
|
export const isProcessCliFailure = (value) => typeof value === "object" &&
|
|
19
21
|
value !== null &&
|
|
@@ -30,7 +32,19 @@ export const captureProcessScenarioFile = async (path, environment = process.env
|
|
|
30
32
|
const parsed = processScenarioSchema.safeParse(input);
|
|
31
33
|
if (!parsed.success)
|
|
32
34
|
throw analysisInputErrorFromIssues("capture_process_scenario", parsed.error.issues, input, { cause: parsed.error });
|
|
33
|
-
const
|
|
35
|
+
const progress = createProgressReporter(async (update) => {
|
|
36
|
+
process.stderr.write(`${JSON.stringify({ rea_progress: update })}\n`);
|
|
37
|
+
}, { minimumIntervalMs: 100 });
|
|
38
|
+
const resourceScope = new ProcessCaptureResourceScope();
|
|
39
|
+
const captured = await captureProcessScenario(parsed.data, signal, process.platform, environment, undefined, undefined, progress, resourceScope);
|
|
40
|
+
try {
|
|
41
|
+
await resourceScope.close();
|
|
42
|
+
}
|
|
43
|
+
catch (cause) {
|
|
44
|
+
if (!captured.ok)
|
|
45
|
+
return cliAnalysisError(captured.error);
|
|
46
|
+
throw cause;
|
|
47
|
+
}
|
|
34
48
|
if (!captured.ok)
|
|
35
49
|
return cliAnalysisError(captured.error);
|
|
36
50
|
return createProcessCaptureEvidence(parsed.data, captured.value);
|
|
@@ -115,24 +129,15 @@ const parseTraceSpecification = (input) => {
|
|
|
115
129
|
};
|
|
116
130
|
const invalidCaptureEvidence = (cause) => new ProcessCliFailure("invalid_input", `Capture evidence is malformed (${describeValidationFailure(cause)}). Create new capture evidence, then try again.`);
|
|
117
131
|
const readJson = async (path) => {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
fatal: true,
|
|
128
|
-
ignoreBOM: true,
|
|
129
|
-
}).decode(bytes);
|
|
130
|
-
const parsed = JSON.parse(text);
|
|
131
|
-
return parsed;
|
|
132
|
-
}
|
|
133
|
-
catch (cause) {
|
|
134
|
-
throw new ProcessCliFailure("invalid_input", `Process input file is not valid UTF-8 JSON: ${path} (${describeValidationFailure(cause)}). Repair the file, then try again.`);
|
|
135
|
-
}
|
|
132
|
+
const loaded = await readJsonFile(path);
|
|
133
|
+
if (loaded.ok)
|
|
134
|
+
return loaded.value;
|
|
135
|
+
if (loaded.error._tag !== "EvidenceFileError")
|
|
136
|
+
throw loaded.error;
|
|
137
|
+
const detail = describeValidationFailure(loaded.error.cause);
|
|
138
|
+
throw new ProcessCliFailure("invalid_input", loaded.error.reason === "invalid-json"
|
|
139
|
+
? `Process input file is not valid UTF-8 JSON: ${path} (${detail}). Repair the file, then try again.`
|
|
140
|
+
: `Process input file could not be read: ${path} (${detail}). Check the reported filesystem constraint and retry.`);
|
|
136
141
|
};
|
|
137
142
|
class ProcessCliFailure extends Error {
|
|
138
143
|
category;
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { posix } from "node:path";
|
|
2
|
+
import { logicalPathNfc } from "../domain/artifactIdentity.js";
|
|
3
|
+
import { compareUnicodeCodePoints } from "../domain/unicodeCodePointOrder.js";
|
|
2
4
|
import { ArtifactReaderFailure } from "./ArtifactReader.js";
|
|
3
5
|
const DRIVE_OR_UNC = /^(?:[A-Za-z]:|\\|\/\/)/u;
|
|
6
|
+
/**
|
|
7
|
+
* English Unicode case folding used only to describe logical names a
|
|
8
|
+
* case-insensitive destination might collapse. It is not a filesystem case table.
|
|
9
|
+
*/
|
|
10
|
+
const ENGLISH_UNICODE_CASE_NOTE = "This comparison is not a filesystem observation.";
|
|
11
|
+
/** Inventory limitation when logical names collide under English Unicode case folding. */
|
|
12
|
+
export const ENGLISH_UNICODE_CASE_INVENTORY_LIMITATION = `Logical archive names collide under English (en-US) Unicode case folding; a case-insensitive destination cannot store both spellings. ${ENGLISH_UNICODE_CASE_NOTE}`;
|
|
13
|
+
/** User-facing prefix for a destination that cannot keep two logical spellings. */
|
|
14
|
+
export const DESTINATION_CASE_COLLISION_PREFIX = "Destination filesystem cannot store both ";
|
|
4
15
|
/** Normalize an untrusted logical archive path without touching filesystem. */
|
|
5
16
|
export const normalizeArtifactPath = (input) => {
|
|
6
17
|
if (input.includes("\0") ||
|
|
@@ -8,7 +19,7 @@ export const normalizeArtifactPath = (input) => {
|
|
|
8
19
|
input.startsWith("/") ||
|
|
9
20
|
DRIVE_OR_UNC.test(input))
|
|
10
21
|
throw new ArtifactReaderFailure("path", `Artifact path is absolute or unsafe: ${JSON.stringify(input)}`);
|
|
11
|
-
const normalized = input
|
|
22
|
+
const normalized = logicalPathNfc(input).replace(/\/+$/u, "");
|
|
12
23
|
const parts = normalized.split("/");
|
|
13
24
|
if (normalized.length === 0 ||
|
|
14
25
|
parts.some((part) => part === "" || part === "." || part === "..") ||
|
|
@@ -16,7 +27,7 @@ export const normalizeArtifactPath = (input) => {
|
|
|
16
27
|
throw new ArtifactReaderFailure("path", `Artifact path is not normalized: ${JSON.stringify(input)}`);
|
|
17
28
|
return normalized;
|
|
18
29
|
};
|
|
19
|
-
/** Reject exact
|
|
30
|
+
/** Reject exact and same-spelling prefix collisions. Case-distinct names stay distinct. */
|
|
20
31
|
export class ArtifactPathRegistry {
|
|
21
32
|
#root = { kind: undefined, children: new Map() };
|
|
22
33
|
add(path, kind) {
|
|
@@ -25,13 +36,10 @@ export class ArtifactPathRegistry {
|
|
|
25
36
|
for (const [index, part] of parts.entries()) {
|
|
26
37
|
if (node.kind !== undefined && node.kind !== "directory")
|
|
27
38
|
throw new ArtifactReaderFailure("path", `Artifact prefix conflict: ${path}`);
|
|
28
|
-
|
|
29
|
-
let child = node.children.get(foldedPart);
|
|
30
|
-
if (child !== undefined && child.spelling !== part)
|
|
31
|
-
throw new ArtifactReaderFailure("path", `Artifact path collision: ${path} differs only in case from ${[...parts.slice(0, index), child.spelling].join("/")}`);
|
|
39
|
+
let child = node.children.get(part);
|
|
32
40
|
if (child === undefined) {
|
|
33
|
-
child = {
|
|
34
|
-
node.children.set(
|
|
41
|
+
child = { kind: undefined, children: new Map() };
|
|
42
|
+
node.children.set(part, child);
|
|
35
43
|
}
|
|
36
44
|
node = child;
|
|
37
45
|
if (index === parts.length - 1) {
|
|
@@ -44,3 +52,116 @@ export class ArtifactPathRegistry {
|
|
|
44
52
|
node.kind = kind;
|
|
45
53
|
}
|
|
46
54
|
}
|
|
55
|
+
const emptyCaseNode = () => ({
|
|
56
|
+
bySpelling: new Map(),
|
|
57
|
+
spellingsByFold: new Map(),
|
|
58
|
+
terminals: [],
|
|
59
|
+
});
|
|
60
|
+
const englishCaseFold = (part) => part.toLocaleLowerCase("en-US");
|
|
61
|
+
/**
|
|
62
|
+
* Record English (en-US) Unicode case collisions on each affected occurrence.
|
|
63
|
+
* Returns the inventory limitation when any logical names collide.
|
|
64
|
+
*/
|
|
65
|
+
export const annotateEnglishUnicodeCaseCollisions = (occurrences) => {
|
|
66
|
+
const collisions = englishUnicodeCaseCollisions(occurrences.map(({ logical_path }) => logical_path));
|
|
67
|
+
if (collisions.size === 0)
|
|
68
|
+
return undefined;
|
|
69
|
+
for (const occurrence of occurrences)
|
|
70
|
+
for (const collision of collisions.get(occurrence.logical_path) ?? [])
|
|
71
|
+
occurrence.limitations.push(caseCollisionLimitation(occurrence.logical_path, collision));
|
|
72
|
+
return ENGLISH_UNICODE_CASE_INVENTORY_LIMITATION;
|
|
73
|
+
};
|
|
74
|
+
const caseCollisionLimitation = (path, { prefix, other, additional }) => {
|
|
75
|
+
const others = additional === 0
|
|
76
|
+
? other
|
|
77
|
+
: `${other} and ${String(additional)} other spelling${additional === 1 ? "" : "s"}`;
|
|
78
|
+
const subject = prefix === path
|
|
79
|
+
? `Logical path ${path} collides`
|
|
80
|
+
: `Logical path ${path} is under ${prefix}, which collides`;
|
|
81
|
+
return `${subject} under English (en-US) Unicode case folding with ${others}; a case-insensitive destination cannot store both. ${ENGLISH_UNICODE_CASE_NOTE}`;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Name the directory-listing spelling that differs from the requested segment
|
|
85
|
+
* only by English (en-US) Unicode case. Exact matches are the same logical name.
|
|
86
|
+
*/
|
|
87
|
+
export const destinationCaseCollisionMessage = (requestedPath, existingNames) => {
|
|
88
|
+
const slash = requestedPath.lastIndexOf("/");
|
|
89
|
+
const segment = slash < 0 ? requestedPath : requestedPath.slice(slash + 1);
|
|
90
|
+
if (existingNames.includes(segment))
|
|
91
|
+
return undefined;
|
|
92
|
+
const folded = englishCaseFold(segment);
|
|
93
|
+
const existing = existingNames
|
|
94
|
+
.filter((name) => englishCaseFold(name) === folded)
|
|
95
|
+
.sort(compareUnicodeCodePoints)[0];
|
|
96
|
+
if (existing === undefined)
|
|
97
|
+
return undefined;
|
|
98
|
+
const parent = slash < 0 ? "" : requestedPath.slice(0, slash + 1);
|
|
99
|
+
return `${DESTINATION_CASE_COLLISION_PREFIX}${requestedPath} and ${parent}${existing}; inventory retains both logical names.`;
|
|
100
|
+
};
|
|
101
|
+
const englishUnicodeCaseCollisions = (paths) => {
|
|
102
|
+
const root = emptyCaseNode();
|
|
103
|
+
for (const path of paths) {
|
|
104
|
+
if (path.length === 0 || path === ".")
|
|
105
|
+
continue;
|
|
106
|
+
let node = root;
|
|
107
|
+
for (const part of path.split("/")) {
|
|
108
|
+
let child = node.bySpelling.get(part);
|
|
109
|
+
if (child === undefined) {
|
|
110
|
+
const folded = englishCaseFold(part);
|
|
111
|
+
const spellings = node.spellingsByFold.get(folded);
|
|
112
|
+
if (spellings === undefined)
|
|
113
|
+
node.spellingsByFold.set(folded, [part]);
|
|
114
|
+
else
|
|
115
|
+
spellings.push(part);
|
|
116
|
+
child = emptyCaseNode();
|
|
117
|
+
node.bySpelling.set(part, child);
|
|
118
|
+
}
|
|
119
|
+
node = child;
|
|
120
|
+
}
|
|
121
|
+
node.terminals.push(path);
|
|
122
|
+
}
|
|
123
|
+
// A collision is recorded once, at the segment where spellings diverge, and
|
|
124
|
+
// shared down the subtree. Pairing every descendant of one spelling with
|
|
125
|
+
// every descendant of another grew quadratically with the subtree sizes.
|
|
126
|
+
// The walk is iterative because a ZIP name can hold more components than
|
|
127
|
+
// the call stack allows.
|
|
128
|
+
const collisions = new Map();
|
|
129
|
+
const pending = [{ node: root, prefix: undefined, chain: undefined }];
|
|
130
|
+
for (let item = pending.pop(); item !== undefined; item = pending.pop()) {
|
|
131
|
+
const { node, prefix, chain } = item;
|
|
132
|
+
if (chain !== undefined)
|
|
133
|
+
for (const path of node.terminals)
|
|
134
|
+
collisions.set(path, collisionsAlong(chain));
|
|
135
|
+
for (const spellings of node.spellingsByFold.values())
|
|
136
|
+
spellings.sort(compareUnicodeCodePoints);
|
|
137
|
+
for (const [spelling, child] of node.bySpelling) {
|
|
138
|
+
const childPrefix = prefix === undefined ? spelling : `${prefix}/${spelling}`;
|
|
139
|
+
const spellings = node.spellingsByFold.get(englishCaseFold(spelling)) ?? [];
|
|
140
|
+
const other = spellings[0] === spelling ? spellings[1] : spellings[0];
|
|
141
|
+
pending.push({
|
|
142
|
+
node: child,
|
|
143
|
+
prefix: childPrefix,
|
|
144
|
+
chain: other === undefined
|
|
145
|
+
? chain
|
|
146
|
+
: {
|
|
147
|
+
collision: {
|
|
148
|
+
prefix: childPrefix,
|
|
149
|
+
other: prefix === undefined ? other : `${prefix}/${other}`,
|
|
150
|
+
additional: spellings.length - 2,
|
|
151
|
+
},
|
|
152
|
+
parent: chain,
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return collisions;
|
|
158
|
+
};
|
|
159
|
+
const collisionsAlong = (chain) => {
|
|
160
|
+
const collisions = [];
|
|
161
|
+
let link = chain;
|
|
162
|
+
while (link !== undefined) {
|
|
163
|
+
collisions.push(link.collision);
|
|
164
|
+
link = link.parent;
|
|
165
|
+
}
|
|
166
|
+
return collisions.reverse();
|
|
167
|
+
};
|
|
@@ -14,10 +14,12 @@ import {} from "../domain/analysisErrorBase.js";
|
|
|
14
14
|
import { interfaceBuilderLimitsSchema } from "../domain/apple/interfaceBuilderGraph.js";
|
|
15
15
|
import { err, ok } from "../domain/result.js";
|
|
16
16
|
import { ArtifactReaderFailure } from "./ArtifactReader.js";
|
|
17
|
+
import { ArtifactResourceScope } from "./ArtifactResourceScope.js";
|
|
17
18
|
import { artifactCapabilities } from "./ArtifactProviderMetadata.js";
|
|
18
19
|
import { ARTIFACT_GRAPH_PROVIDER } from "../application/InvestigationProviders.js";
|
|
19
20
|
import { createEvidence } from "../domain/evidence.js";
|
|
20
21
|
import { createArtifactInspection } from "../domain/artifactInspection.js";
|
|
22
|
+
import { ProviderCleanupError } from "../domain/providerCleanupError.js";
|
|
21
23
|
/** Read-only inventory and exclusively owned extraction provider. */
|
|
22
24
|
export class ArtifactProvider {
|
|
23
25
|
#capabilities;
|
|
@@ -42,6 +44,7 @@ class ArtifactClient {
|
|
|
42
44
|
target;
|
|
43
45
|
environment;
|
|
44
46
|
platform;
|
|
47
|
+
#resourceScope = new ArtifactResourceScope();
|
|
45
48
|
constructor(target, environment, platform) {
|
|
46
49
|
this.target = target;
|
|
47
50
|
this.environment = environment;
|
|
@@ -125,15 +128,15 @@ class ArtifactClient {
|
|
|
125
128
|
inputFormat: this.target.format,
|
|
126
129
|
outputRoot: parsed.output_root,
|
|
127
130
|
environment: this.environment,
|
|
131
|
+
integrityPolicy: parsed.integrity_policy,
|
|
132
|
+
resourceScope: this.#resourceScope,
|
|
128
133
|
}, options?.signal);
|
|
129
134
|
return ok(createAnalysisExecution(result, ARTIFACT_GRAPH_PROVIDER, {
|
|
130
135
|
rawResult: null,
|
|
131
136
|
limitations: result.limitations,
|
|
132
137
|
subject: subjectFor(this.target.sourcePath ?? this.target.path, result.manifest),
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
path,
|
|
136
|
-
})),
|
|
138
|
+
// Each extracted file's path is already in artifacts.
|
|
139
|
+
locations: [],
|
|
137
140
|
}));
|
|
138
141
|
}
|
|
139
142
|
const parsed = artifactInventoryInputSchema.parse(parameters);
|
|
@@ -142,10 +145,8 @@ class ArtifactClient {
|
|
|
142
145
|
rawResult: null,
|
|
143
146
|
limitations: result.limitations,
|
|
144
147
|
subject: subjectFor(this.target.sourcePath ?? this.target.path, result.manifest),
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
path,
|
|
148
|
-
})),
|
|
148
|
+
// Each occurrence's logical path is already in the result.
|
|
149
|
+
locations: [],
|
|
149
150
|
}));
|
|
150
151
|
}
|
|
151
152
|
catch (cause) {
|
|
@@ -153,7 +154,13 @@ class ArtifactClient {
|
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
156
|
close() {
|
|
156
|
-
return
|
|
157
|
+
return this.#resourceScope.close().then(() => ok(null), (cause) => {
|
|
158
|
+
const failure = cause instanceof ArtifactReaderFailure ? cause : undefined;
|
|
159
|
+
return err(new ProviderCleanupError(ARTIFACT_GRAPH_PROVIDER.id, failure?.cleanup?.resources ?? ["artifact resources"], {
|
|
160
|
+
reason: failure?.cleanup?.reason ??
|
|
161
|
+
(cause instanceof Error ? cause.message : String(cause)),
|
|
162
|
+
}, { cause, operation: "close_binary" }));
|
|
163
|
+
});
|
|
157
164
|
}
|
|
158
165
|
/** The active target's kind is outside this operation's supported targets. */
|
|
159
166
|
unsupportedTarget(operation, reason) {
|
|
@@ -217,17 +224,14 @@ class ArtifactClient {
|
|
|
217
224
|
});
|
|
218
225
|
const inventory = await this.inventory(inventoryParameters, options);
|
|
219
226
|
const subject = subjectFor(this.target.sourcePath ?? this.target.path, inventory.manifest);
|
|
220
|
-
const locations = inventory.occurrences.map(({ logical_path: path }) => ({
|
|
221
|
-
kind: "artifact-path",
|
|
222
|
-
path,
|
|
223
|
-
}));
|
|
224
227
|
const inventoryEvidence = createEvidence(subject, ARTIFACT_GRAPH_PROVIDER, {
|
|
225
228
|
operation: "inventory_artifact",
|
|
226
229
|
parameters: inventoryParameters,
|
|
227
230
|
result: inventory,
|
|
228
231
|
rawResult: null,
|
|
229
232
|
limitations: inventory.limitations,
|
|
230
|
-
|
|
233
|
+
// The nested inventory already names every occurrence's logical path.
|
|
234
|
+
locations: [],
|
|
231
235
|
});
|
|
232
236
|
const result = createArtifactInspection(inventoryEvidence);
|
|
233
237
|
await options?.progress?.report({
|
|
@@ -240,11 +244,12 @@ class ArtifactClient {
|
|
|
240
244
|
rawResult: null,
|
|
241
245
|
limitations: result.limitations,
|
|
242
246
|
subject,
|
|
243
|
-
locations,
|
|
247
|
+
locations: [],
|
|
244
248
|
}));
|
|
245
249
|
}
|
|
246
250
|
inventory(parsed, options) {
|
|
247
251
|
return inventoryArtifact(this.target.sourcePath ?? this.target.path, {
|
|
252
|
+
resourceScope: this.#resourceScope,
|
|
248
253
|
environment: this.environment,
|
|
249
254
|
...(options?.signal === undefined ? {} : { signal: options.signal }),
|
|
250
255
|
integrity: { mode: parsed.integrity_policy },
|
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
/** Snapshot mutable entry metadata before the producer later validates open(). */
|
|
2
|
+
export const copyArtifactEntry = (entry) => ({
|
|
3
|
+
...entry,
|
|
4
|
+
limitations: [...entry.limitations],
|
|
5
|
+
...(entry.sourceIdentity === undefined
|
|
6
|
+
? {}
|
|
7
|
+
: { sourceIdentity: { ...entry.sourceIdentity } }),
|
|
8
|
+
});
|
|
9
|
+
/** Compare every portable and adapter-owned fact supplied with an entry. */
|
|
10
|
+
export const sameArtifactEntry = (entry, produced) => entry.path === produced.path &&
|
|
11
|
+
entry.kind === produced.kind &&
|
|
12
|
+
entry.declaredSize === produced.declaredSize &&
|
|
13
|
+
entry.compressedSize === produced.compressedSize &&
|
|
14
|
+
entry.executable === produced.executable &&
|
|
15
|
+
entry.encrypted === produced.encrypted &&
|
|
16
|
+
entry.byteOffset === produced.byteOffset &&
|
|
17
|
+
entry.declaredSha256 === produced.declaredSha256 &&
|
|
18
|
+
entry.unpacked === produced.unpacked &&
|
|
19
|
+
entry.adapterKey === produced.adapterKey &&
|
|
20
|
+
entry.limitations.length === produced.limitations.length &&
|
|
21
|
+
entry.limitations.every((limitation, index) => limitation === produced.limitations[index]) &&
|
|
22
|
+
entry.sourceIdentity?.device === produced.sourceIdentity?.device &&
|
|
23
|
+
entry.sourceIdentity?.inode === produced.sourceIdentity?.inode;
|
|
1
24
|
/** Typed adapter failure translated at provider boundary. */
|
|
2
25
|
export class ArtifactReaderFailure extends Error {
|
|
3
26
|
reason;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { ArtifactReaderFailure } from "./ArtifactReader.js";
|
|
2
|
+
/** Caller-owned scope that retains failed artifact cleanup for a later close. */
|
|
3
|
+
export class ArtifactResourceScope {
|
|
4
|
+
#pending = new Set();
|
|
5
|
+
#active = new Set();
|
|
6
|
+
#draining;
|
|
7
|
+
#closed = false;
|
|
8
|
+
/** Admit a resource operation while the scope remains open. */
|
|
9
|
+
async run(operation) {
|
|
10
|
+
while (true) {
|
|
11
|
+
if (this.#closed)
|
|
12
|
+
throw new ArtifactReaderFailure("unavailable", "Artifact resource scope is closed");
|
|
13
|
+
if (this.#draining !== undefined)
|
|
14
|
+
await this.#draining;
|
|
15
|
+
if (this.#closed)
|
|
16
|
+
throw new ArtifactReaderFailure("unavailable", "Artifact resource scope is closed");
|
|
17
|
+
if (this.#pending.size > 0) {
|
|
18
|
+
await this.#retryCleanup();
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const running = Promise.resolve().then(operation);
|
|
22
|
+
this.#active.add(running);
|
|
23
|
+
try {
|
|
24
|
+
return await running;
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
this.#active.delete(running);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Attempt cleanup now and retain the same owner if it fails. */
|
|
32
|
+
async release(owner) {
|
|
33
|
+
try {
|
|
34
|
+
await cleanup(owner);
|
|
35
|
+
this.#pending.delete(owner);
|
|
36
|
+
return { kind: "released" };
|
|
37
|
+
}
|
|
38
|
+
catch (cause) {
|
|
39
|
+
this.#pending.add(owner);
|
|
40
|
+
return { kind: "failed", cause };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** Retry retained owners without closing resource admission. */
|
|
44
|
+
#retryCleanup() {
|
|
45
|
+
if (this.#draining !== undefined)
|
|
46
|
+
return this.#draining;
|
|
47
|
+
this.#draining = this.#drainAndRetry().finally(() => {
|
|
48
|
+
this.#draining = undefined;
|
|
49
|
+
});
|
|
50
|
+
return this.#draining;
|
|
51
|
+
}
|
|
52
|
+
/** Stop admission, wait for active operations, and retry every retained owner. */
|
|
53
|
+
close() {
|
|
54
|
+
this.#closed = true;
|
|
55
|
+
return this.#retryCleanup();
|
|
56
|
+
}
|
|
57
|
+
async #drainAndRetry() {
|
|
58
|
+
while (this.#active.size > 0)
|
|
59
|
+
await Promise.allSettled(this.#active);
|
|
60
|
+
const failures = [];
|
|
61
|
+
for (const owner of this.#pending) {
|
|
62
|
+
try {
|
|
63
|
+
await cleanup(owner);
|
|
64
|
+
this.#pending.delete(owner);
|
|
65
|
+
}
|
|
66
|
+
catch (cause) {
|
|
67
|
+
failures.push({ owner, cause });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (failures.length === 0)
|
|
71
|
+
return;
|
|
72
|
+
const observations = failures.map(({ owner, cause }) => ArtifactReaderFailure.cleanupObservation(cause, owner.resource));
|
|
73
|
+
const resources = [
|
|
74
|
+
...new Set(observations.flatMap(({ resources }) => resources)),
|
|
75
|
+
];
|
|
76
|
+
throw new ArtifactReaderFailure("unavailable", `Artifact cleanup remains incomplete: ${resources.join(", ")}`, {
|
|
77
|
+
cause: new AggregateError(failures.map(({ cause }) => cause), "One or more artifact resources remain owned"),
|
|
78
|
+
cleanup: {
|
|
79
|
+
reason: observations.map(({ reason }) => reason).join("; "),
|
|
80
|
+
resources,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const cleanup = async (owner) => {
|
|
86
|
+
switch (owner.kind) {
|
|
87
|
+
case "javascript-source-analysis":
|
|
88
|
+
await owner.analysis.close();
|
|
89
|
+
return;
|
|
90
|
+
case "reader":
|
|
91
|
+
await owner.reader.close();
|
|
92
|
+
return;
|
|
93
|
+
case "file-handle":
|
|
94
|
+
case "directory-handle":
|
|
95
|
+
await owner.handle.close();
|
|
96
|
+
return;
|
|
97
|
+
case "output-tree":
|
|
98
|
+
await owner.tree.rollback();
|
|
99
|
+
}
|
|
100
|
+
};
|