rea-agents 6.1.0 → 6.2.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 -5
- package/bridge/ghidra/ReaGhidraBridge.java +32 -4
- package/bridge/hopper_bridge.py +6 -1
- package/dist/android/JadxConfiguration.js +87 -7
- package/dist/android/JadxMcpTransport.js +14 -2
- package/dist/android/JadxProvider.js +57 -35
- package/dist/application/BinaryTargetResolver.js +5 -3
- package/dist/application/BrowserEvidence.js +3 -8
- package/dist/application/BrowserScenarioEvidence.js +2 -18
- package/dist/application/CapabilityInventory.js +43 -9
- package/dist/application/ClientConfigurationDocument.js +69 -25
- package/dist/application/DirectAnalysis.js +29 -14
- package/dist/application/DirectAnalysisCleanup.js +72 -0
- package/dist/application/DirectAnalysisStatus.js +4 -5
- package/dist/application/Doctor.js +15 -19
- package/dist/application/DoctorDiagnostics.js +1 -2
- package/dist/application/EnhancedTools.js +51 -6
- package/dist/application/EvidenceBundleFiles.js +8 -3
- package/dist/application/InvestigationProviders.js +9 -1
- package/dist/application/JsonFiles.js +42 -9
- package/dist/application/LinuxHopper.js +9 -6
- package/dist/application/MacHopper.js +15 -18
- package/dist/application/RealHopperAssertions.js +0 -11
- package/dist/application/ReconstructionObligationCandidates.js +1 -1
- package/dist/application/ReferenceSourceImportEntries.js +1 -1
- package/dist/application/Setup.js +8 -16
- package/dist/application/SetupHost.js +16 -27
- package/dist/application/SetupPlan.js +6 -6
- package/dist/application/Uninstall.js +81 -29
- package/dist/application/UpdateMaintenance.js +7 -5
- package/dist/application/UpdateRuntime.js +12 -12
- package/dist/application/WebScriptExportService.js +30 -4
- package/dist/application/WorkflowEvidence.js +25 -2
- package/dist/application/XrefsAddressResolution.js +45 -0
- package/dist/application/analysisView/AnalysisViewService.js +76 -0
- package/dist/application/binary/AnalysisClientCleanup.js +30 -5
- package/dist/application/binary/AnalysisProviderEvaluation.js +1 -2
- package/dist/application/binary/AnalysisProviderRegistry.js +2 -6
- package/dist/application/binary/AnalysisSnapshotCache.js +10 -8
- package/dist/application/binary/BinarySession.js +70 -29
- package/dist/application/binary/BinarySessionComposition.js +1 -3
- package/dist/application/binary/BinarySessionExecution.js +3 -5
- package/dist/application/binary/BinarySessionOpen.js +1 -1
- package/dist/application/binary/BinarySessionRecords.js +1 -1
- package/dist/application/binary/BinarySessionStatus.js +1 -6
- package/dist/application/binary/CompositeProvider.js +4 -18
- package/dist/application/binary/LazyAnalysisProvider.js +5 -5
- package/dist/application/binary/SessionProviderRouter.js +27 -135
- package/dist/application/homebrew.js +48 -0
- package/dist/application/javascript/ElectronActiveEvidence.js +9 -13
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +2 -6
- package/dist/application/javascript/JavaScriptApplicationService.js +6 -1
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -3
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +11 -9
- package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
- package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
- package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
- package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +12 -3
- package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +43 -16
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +46 -6
- package/dist/application/javascript/JavaScriptModuleRelationships.js +1 -1
- package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -3
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -2
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +1 -5
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +75 -46
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +42 -19
- package/dist/application/managed/ManagedMemberComparisonService.js +2 -1
- package/dist/application/managed/ManagedNativeVerificationService.js +2 -1
- package/dist/application/process/ProcessCli.js +11 -11
- package/dist/application/process/ProcessEvidence.js +0 -1
- package/dist/artifacts/ArtifactProvider.js +39 -14
- package/dist/artifacts/ArtifactReader.js +31 -0
- package/dist/artifacts/DirectoryArtifactReader.js +2 -1
- package/dist/artifacts/MachOSliceArtifactReader.js +9 -2
- package/dist/artifacts/NativeDmgArtifactReader.js +65 -20
- package/dist/artifacts/SafeOutputTree.js +16 -2
- package/dist/artifacts/ZipArtifactReader.js +11 -4
- package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +4 -2
- package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
- package/dist/artifacts/apple/KeyedArchiveReader.js +21 -3
- package/dist/artifacts/extraction/ArtifactExtraction.js +78 -21
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +67 -61
- package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
- package/dist/artifacts/inventory/reader.js +3 -3
- package/dist/artifacts/inventory/scanCanonical.js +48 -24
- package/dist/artifacts/inventory/scanReader.js +5 -9
- package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
- package/dist/browser/CdpBrowserProvider.js +2 -3
- package/dist/browser/CdpCaptureEventHandlers.js +2 -4
- package/dist/browser/CdpCaptureEvents.js +0 -1
- package/dist/browser/CdpCaptureValues.js +20 -0
- package/dist/browser/CdpElectronProvider.js +0 -2
- package/dist/browser/CdpElectronScriptEvents.js +2 -8
- package/dist/browser/CdpElectronScripts.js +2 -3
- package/dist/browser/CdpPageCaptureScripts.js +2 -3
- package/dist/browser/CdpSafeMetadata.js +10 -10
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +59 -44
- package/dist/browser/PlaywrightElectronActiveActions.js +2 -56
- package/dist/browser/PlaywrightElectronActiveProvider.js +10 -6
- package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
- package/dist/browser/PlaywrightScenarioBrowser.js +139 -39
- package/dist/browser/PlaywrightScenarioEvents.js +1 -1
- package/dist/browser/PlaywrightScenarioSession.js +39 -22
- package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
- package/dist/browser/history/CaptureFailures.js +6 -2
- package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
- package/dist/catalogIdentity.js +0 -1
- package/dist/cli/analysisViewCommands.js +36 -0
- package/dist/cli/artifactCommands.js +11 -12
- package/dist/cli/coreAnalysisCommands.js +3 -3
- package/dist/cli/coreBinaryCommands.js +32 -27
- package/dist/cli/coreNativeCommands.js +9 -10
- package/dist/cli/electronCommands.js +4 -4
- package/dist/cli/interactiveSetup.js +6 -6
- package/dist/cli/managedCommands.js +7 -8
- package/dist/cli/nativeCallCommands.js +1 -2
- package/dist/cli/omittableDefaults.js +50 -0
- package/dist/cli/processCommands.js +3 -2
- package/dist/cli/setupCommands.js +16 -15
- package/dist/cli/utilityCommands.js +9 -9
- package/dist/cli.js +16 -8
- package/dist/cliBrowserScenarioCommands.js +2 -2
- package/dist/cliCommandNames.js +1 -0
- package/dist/cliJsonInput.js +15 -1
- package/dist/cliOutput.js +0 -38
- package/dist/composition/auxiliaryAnalysisProviders.js +27 -23
- package/dist/composition/binary.js +9 -9
- package/dist/composition/browserScenario.js +2 -1
- package/dist/composition/directAnalysis.js +20 -13
- package/dist/composition/electronScenario.js +1 -1
- package/dist/composition/optionalObservationProviders.js +12 -7
- package/dist/config/environment.js +6 -0
- package/dist/config/ghidraStartupTimeout.js +4 -9
- package/dist/config/homeDirectory.js +12 -0
- package/dist/config/mcpResponseBudget.js +9 -1
- package/dist/config/parseConfig.js +7 -3
- package/dist/config/parsers.js +19 -22
- package/dist/contracts/analysisViewToolContracts.js +56 -0
- package/dist/contracts/applicationToolContracts.js +5 -4
- package/dist/contracts/artifactComparisonExample.js +2 -2
- package/dist/contracts/artifactToolContracts.js +1 -1
- package/dist/contracts/browserScenarioToolContracts.js +1 -1
- package/dist/contracts/browserToolContracts.js +19 -15
- package/dist/contracts/enhancedInputs.js +2 -2
- package/dist/contracts/enhancedToolContracts.js +4 -3
- package/dist/contracts/evm/evmToolContracts.js +1 -1
- package/dist/contracts/functionWorkflowToolContracts.js +1 -1
- package/dist/contracts/inputSchemaPresentation.js +90 -0
- package/dist/contracts/investigationExamples.js +4 -3
- package/dist/contracts/javascript/electronToolContracts.js +1 -1
- package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +0 -20
- package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +245 -0
- package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
- package/dist/contracts/managed/managedToolContracts.js +5 -10
- package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
- package/dist/contracts/mobileApplicationGraphExamples.js +3 -3
- package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
- package/dist/contracts/native/nativeToolContracts.js +2 -2
- package/dist/contracts/officialToolContracts.js +2 -1
- package/dist/contracts/promptContracts.js +2 -2
- package/dist/contracts/providerSelection.js +1 -1
- package/dist/contracts/sessionToolContracts.js +14 -2
- package/dist/contracts/sessionToolSchemas.js +1 -14
- package/dist/contracts/toolContracts.js +2 -0
- package/dist/contracts/toolEffects.js +1 -0
- package/dist/contracts/toolOutputSchemaGroups.js +136 -92
- package/dist/contracts/toolOutputSchemaPrimitives.js +11 -21
- package/dist/contracts/toolSchemaMetadata.js +18 -69
- package/dist/contracts/webNetworkCaptureToolContracts.js +1 -1
- package/dist/contracts/webRuntimeToolContracts.js +1 -1
- package/dist/contracts/webScriptToolContracts.js +1 -1
- package/dist/doctorRuntime.js +7 -5
- package/dist/domain/analysisErrorCore.js +3 -0
- package/dist/domain/analysisErrorPresentation.js +18 -3
- package/dist/domain/analysisErrorProjection.js +24 -5
- package/dist/domain/analysisSnapshot.js +29 -31
- package/dist/domain/analysisView/analysisView.js +243 -0
- package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
- package/dist/domain/analysisView/binaryLayoutView.js +159 -0
- package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
- package/dist/domain/android/androidApplication.js +1 -1
- package/dist/domain/apple/appleApplication.js +1 -1
- package/dist/domain/apple/dylibResolution.js +10 -3
- package/dist/domain/apple/interfaceBuilderGraph.js +0 -1
- package/dist/domain/apple/keyedArchive.js +26 -2
- package/dist/domain/artifactComparison.js +15 -6
- package/dist/domain/artifactGraph.js +16 -3
- package/dist/domain/artifactInventoryEvidence.js +9 -16
- package/dist/domain/artifactOperationError.js +3 -3
- package/dist/domain/artifactPartialObservation.js +1 -0
- package/dist/domain/artifactPathSyntax.js +49 -0
- package/dist/domain/binaryTarget.js +39 -13
- package/dist/domain/browserCaptureComparison.js +13 -49
- package/dist/domain/browserNetworkEvidence.js +10 -4
- package/dist/domain/browserObservation.js +0 -1
- package/dist/domain/browserObservationSchemas.js +14 -3
- package/dist/domain/browserScenario.js +0 -1
- package/dist/domain/browserScenarioCapture.js +1 -2
- package/dist/domain/browserScenarioDiff.js +0 -2
- package/dist/domain/browserScenarioDiffEvidence.js +0 -12
- package/dist/domain/browserScenarioDiffValues.js +2 -2
- package/dist/domain/browserScenarioValues.js +3 -4
- package/dist/domain/callPath.js +8 -9
- package/dist/domain/callPathSchemas.js +2 -2
- package/dist/domain/changedBehavior.js +3 -3
- package/dist/domain/completionLedgerGeneration.js +2 -1
- package/dist/domain/configurationErrors.js +12 -0
- package/dist/domain/conformancePackage.js +4 -3
- package/dist/domain/evidence.js +10 -36
- package/dist/domain/evidenceBundle.js +7 -9
- package/dist/domain/evidenceCompletionLedger.js +2 -1
- package/dist/domain/functionComparison.js +4 -5
- package/dist/domain/functionComparisonDimensions.js +120 -87
- package/dist/domain/functionComparisonNormalization.js +23 -34
- package/dist/domain/functionComparisonResults.js +1 -4
- package/dist/domain/functionComparisonSchemas.js +2 -8
- package/dist/domain/functionDossierEvidence.js +2 -37
- package/dist/domain/javascript/electronActiveObservation.js +26 -69
- package/dist/domain/javascript/electronObservation.js +14 -3
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +10 -9
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +2 -1
- package/dist/domain/javascript/electronStaticAnalysisNative.js +2 -1
- package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +2 -0
- package/dist/domain/javascript/javascriptApplicationGraph.js +26 -3
- package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +5 -2
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +2 -1
- package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
- package/dist/domain/javascript/javascriptExportShapeComparison.js +7 -1
- package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
- package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +29 -1
- package/dist/domain/javascript/javascriptExportShapeSelection.js +5 -5
- package/dist/domain/javascript/javascriptExportShapeVariants.js +67 -14
- package/dist/domain/javascript/javascriptFeatureSeed.js +20 -0
- package/dist/domain/javascript/javascriptFeatureTraversal.js +0 -1
- package/dist/domain/javascript/javascriptNativeHandoff.js +1 -1
- package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
- package/dist/domain/javascript/javascriptRuntimeObservation.js +10 -2
- package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +1 -1
- package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +3 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +0 -1
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +9 -3
- package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
- package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
- package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -1
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +1 -1
- package/dist/domain/javascript/javascriptSemanticGraph.js +88 -46
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +77 -20
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +21 -27
- package/dist/domain/javascript/javascriptSemanticObjects.js +83 -42
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +1 -12
- package/dist/domain/javascript/javascriptSemanticProjection.js +2 -3
- package/dist/domain/javascript/javascriptSemanticPromises.js +2 -1
- package/dist/domain/javascript/javascriptSemanticResourceLimits.js +1 -1
- package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
- package/dist/domain/javascript/javascriptSemanticReturns.js +32 -17
- package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
- package/dist/domain/javascript/javascriptSemanticValues.js +47 -54
- package/dist/domain/javascript/javascriptSourceMapPaths.js +104 -0
- package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +2 -1
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +0 -1
- package/dist/domain/javascript/sourceToBundleComparison.js +12 -3
- package/dist/domain/javascript/sourceToBundleSignals.js +47 -19
- package/dist/domain/localPath.js +1 -1
- package/dist/domain/managed/managedArtifact.js +6 -4
- package/dist/domain/managed/managedMemberComparison.js +2 -9
- package/dist/domain/managed/managedNativeVerification.js +0 -2
- package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
- package/dist/domain/native/binaryLayout.js +2 -3
- package/dist/domain/native/nativeApiBoundary.js +1 -1
- package/dist/domain/native/nativeCallObservation.js +5 -3
- package/dist/domain/native/nativeInstruction.js +7 -0
- package/dist/domain/native/recordedCrash.js +2 -3
- package/dist/domain/offsetDateTime.js +17 -0
- package/dist/domain/process/processCapture.js +13 -12
- package/dist/domain/process/processCaptureCoverage.js +67 -0
- package/dist/domain/process/processCaptureExample.js +2 -1
- package/dist/domain/process/processCaptureParsing.js +1 -34
- package/dist/domain/process/processCaptureValidation.js +81 -13
- package/dist/domain/process/processComparison.js +41 -22
- package/dist/domain/process/processObservation.js +10 -2
- package/dist/domain/process/processScenario.js +24 -2
- package/dist/domain/process/processTraceComparison.js +0 -2
- package/dist/domain/process/processTraceDimensionProjection.js +1 -1
- package/dist/domain/process/processTraceEvaluation.js +15 -11
- package/dist/domain/process/processTraceSpecification.js +3 -4
- package/dist/domain/providerAdapterError.js +2 -0
- package/dist/domain/reconstructionCoverage.js +5 -2
- package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
- package/dist/domain/reconstructionReadinessSchemas.js +2 -1
- package/dist/domain/reconstructionVerification.js +3 -3
- package/dist/domain/reconstructionVerificationSchemas.js +2 -1
- package/dist/domain/referenceSourceGraph.js +20 -21
- package/dist/domain/staticRuntimeCorrelation.js +2 -2
- package/dist/domain/stringPatterns.js +6 -0
- package/dist/domain/swiftSymbolClassification.js +61 -0
- package/dist/domain/symbolAnalysis.js +66 -18
- package/dist/domain/webCaptureDiff.js +0 -1
- package/dist/domain/webCaptureDiffSchemas.js +6 -3
- package/dist/domain/webEventListeners.js +3 -2
- package/dist/domain/webExecution.js +3 -2
- package/dist/domain/webRuntime.js +0 -2
- package/dist/domain/webScriptExport.js +1 -1
- package/dist/dotnet/ManagedArtifactInspector.js +2 -19
- package/dist/dotnet/ManagedMemberInspector.js +12 -18
- package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
- package/dist/dotnet/ManagedMemberRows.js +75 -62
- package/dist/dotnet/ManagedMetadataInventory.js +16 -22
- package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
- package/dist/dotnet/ManagedReaderFailure.js +16 -0
- package/dist/dotnet/ManagedStaticProvider.js +3 -5
- package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
- package/dist/evaluation/AgentEvaluationReport.js +28 -0
- package/dist/evaluation/CodexAgentEval.js +12 -8
- package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
- package/dist/evm/EvmoleInterfaceProvider.js +2 -1
- package/dist/firmware/FirmwareCommand.js +9 -5
- package/dist/firmware/FirmwareProvider.js +4 -4
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +3 -6
- package/dist/ghidra/GhidraClient.js +91 -32
- package/dist/ghidra/GhidraClientStartup.js +0 -2
- package/dist/ghidra/GhidraDoctor.js +6 -5
- package/dist/ghidra/GhidraFunctionValues.js +3 -5
- package/dist/ghidra/GhidraInstallation.js +40 -12
- package/dist/ghidra/GhidraJavaLaunch.js +6 -2
- package/dist/ghidra/GhidraLauncher.js +15 -7
- package/dist/ghidra/GhidraProvider.js +6 -2
- package/dist/ghidra/GhidraProviderCapabilities.js +6 -0
- package/dist/ghidra/GhidraProviderClient.js +13 -3
- package/dist/ghidra/GhidraSessionError.js +2 -0
- package/dist/ghidra/GhidraSessionRoot.js +39 -0
- package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
- package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
- package/dist/hopper/BridgeLauncher.js +34 -45
- package/dist/hopper/HopperAnalysisProfile.js +3 -8
- package/dist/hopper/HopperCleanup.js +56 -27
- package/dist/hopper/HopperClient.js +86 -65
- package/dist/hopper/HopperMachOImage.js +3 -2
- package/dist/hopper/HopperProvider.js +16 -18
- package/dist/hopper/HopperRegexSearch.js +3 -6
- package/dist/hopper/HopperTargetLease.js +132 -49
- package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
- package/dist/ida/IdaConfiguration.js +8 -3
- package/dist/ida/IdaInput.js +1 -7
- package/dist/ida/IdaMcpConnection.js +8 -4
- package/dist/ida/IdaOperationRunner.js +3 -3
- package/dist/ida/IdaProvider.js +8 -12
- package/dist/ida/IdaSessionClient.js +20 -18
- package/dist/ida/IdaWorkspace.js +12 -13
- package/dist/inspector/V8InspectorCaptureProjection.js +1 -1
- package/dist/inspector/V8InspectorProvider.js +38 -28
- package/dist/javascript/recovery/WakaruCommand.js +7 -2
- package/dist/javascript/recovery/WakaruExecution.js +5 -2
- package/dist/main/shutdown.js +11 -3
- package/dist/main/startup.js +9 -2
- package/dist/main/transport.js +22 -2
- package/dist/main.js +11 -18
- package/dist/native/AppleMachoSelection.js +16 -6
- package/dist/native/CommandRunner.js +9 -7
- package/dist/native/LldbCallTracer.js +8 -2
- package/dist/native/NativeMacOSProvider.js +25 -15
- package/dist/native/NativeUiHelperRuntime.js +11 -2
- package/dist/native/NativeUiObservation.js +2 -2
- package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
- package/dist/process/DarwinProcessRunTokenReader.js +16 -2
- package/dist/process/ExecFileOutput.js +88 -6
- package/dist/process/PrivateRuntimeRoot.js +10 -5
- package/dist/process/ProcessOwnership.js +1 -4
- package/dist/process/ProcessOwnershipObservation.js +11 -5
- package/dist/process/ProviderProcess.js +1 -3
- package/dist/process/capture/FilesystemSnapshot.js +50 -13
- package/dist/process/capture/ProcessCaptureError.js +13 -0
- package/dist/process/capture/ProcessCaptureLifecycle.js +158 -70
- package/dist/process/capture/ProcessFilesystemEffects.js +33 -3
- package/dist/process/capture/ProcessHarness.js +21 -25
- package/dist/process/capture/ProcessNormalization.js +20 -2
- package/dist/process/capture/ProcessSampling.js +25 -2
- package/dist/process/capture/TerminalRenderer.js +14 -0
- package/dist/process/snapshotEnvironment.js +14 -0
- package/dist/server/EvidenceMcpServer.js +25 -14
- package/dist/server/createServer.js +49 -36
- package/dist/server/mcpClientMetadata.js +12 -5
- package/dist/server/promptCompletion.js +3 -8
- package/dist/server/registerAnalysisViewTool.js +15 -0
- package/dist/server/registerAndroidTools.js +2 -3
- package/dist/server/registerApplicationTools/compareExportShapes.js +4 -5
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
- package/dist/server/registerApplicationTools/compareVersions.js +4 -5
- package/dist/server/registerApplicationTools/coverage.js +1 -2
- package/dist/server/registerApplicationTools/helpers.js +1 -2
- package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
- package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
- package/dist/server/registerApplicationTools/traceFeature.js +4 -5
- package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
- package/dist/server/registerArtifactComparisonTool.js +4 -5
- package/dist/server/registerBinaryDiagnosticsTools.js +2 -3
- package/dist/server/registerBrowserScenarioTool.js +3 -4
- package/dist/server/registerBrowserTools.js +13 -16
- package/dist/server/registerBundleComparisonTool.js +5 -6
- package/dist/server/registerCloseLifecycleTool.js +2 -3
- package/dist/server/registerElectronTools.js +10 -13
- package/dist/server/registerEnhancedTools.js +23 -23
- package/dist/server/registerEvidenceTools.js +3 -4
- package/dist/server/registerEvmTools.js +2 -3
- package/dist/server/registerFirmwareTools.js +2 -3
- package/dist/server/registerFunctionComparisonTool.js +7 -8
- package/dist/server/registerInvestigationTools.js +14 -15
- package/dist/server/registerJavaScriptRecoveryTool.js +2 -3
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -6
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -6
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -5
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -7
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -7
- package/dist/server/registerOfficialTools.js +4 -19
- package/dist/server/registerProcessComparisonTool.js +8 -8
- package/dist/server/registerRecordedCrashTools.js +2 -3
- package/dist/server/registerSessionRecordTools.js +15 -19
- package/dist/server/registerSessionStatusTool.js +3 -4
- package/dist/server/registerSessionTools.js +12 -18
- package/dist/server/registerWebModuleTool.js +2 -3
- package/dist/server/registerWebNetworkCaptureTool.js +2 -3
- package/dist/server/registerWebRuntimeTools.js +4 -5
- package/dist/server/registerWebScriptTool.js +2 -3
- package/dist/server/registerWebSourceLocationTool.js +2 -3
- package/dist/server/toolResult.js +66 -94
- package/dist/server/toolResultEncoding.js +11 -10
- package/dist/windows/WindowsNativeLoader.js +1 -0
- package/dist/windows/WindowsOwnedProcess.js +60 -15
- package/dist/windows/WindowsPrivateRuntime.js +7 -8
- package/native/windows/README.md +3 -1
- package/native/windows/build/manifest.json +2 -2
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +39 -30
- package/scripts/rea.mjs +3 -6
- package/skills/reverse-engineer-anything/SKILL.md +9 -8
- package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
- package/skills/reverse-engineer-anything/references/javascript-applications.md +16 -6
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
- package/dist/config.js +0 -1
- package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
- package/dist/contracts/process/processCaptureExample.js +0 -2
- package/dist/contracts/toolOutputSchemas.js +0 -2
- package/dist/main/reload.js +0 -12
- package/dist/main/state.js +0 -3
- package/dist/server/sessionToolPolicies.js +0 -2
|
@@ -3,7 +3,7 @@ import { constants } from "node:fs";
|
|
|
3
3
|
import { open, realpath, writeFile, mkdir } from "node:fs/promises";
|
|
4
4
|
import { isAbsolute, join } from "node:path";
|
|
5
5
|
import { z } from "zod";
|
|
6
|
-
import { AnalysisCancelledError } from "../../domain/analysisErrorCore.js";
|
|
6
|
+
import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisUnsupportedTargetError, } from "../../domain/analysisErrorCore.js";
|
|
7
7
|
import { ProviderAdapterError } from "../../domain/providerAdapterError.js";
|
|
8
8
|
import { jsonObjectSchema } from "../../domain/jsonValue.js";
|
|
9
9
|
import { err, ok } from "../../domain/result.js";
|
|
@@ -11,7 +11,7 @@ import { nativeAotAdapter } from "./nativeaot/NativeAotAdapter.js";
|
|
|
11
11
|
const digest = z.string().regex(/^[a-f0-9]{64}$/u);
|
|
12
12
|
/** Exact executable extension artifact committed before the session starts. */
|
|
13
13
|
export const ghidraExtensionSchema = z.strictObject({
|
|
14
|
-
id: z.string().regex(/^[a-z][a-z0-9
|
|
14
|
+
id: z.string().regex(/^[a-z][a-z0-9\x2d]*$/u),
|
|
15
15
|
path: z.string().refine(isAbsolute, "Extension path must be absolute"),
|
|
16
16
|
configured_path: z
|
|
17
17
|
.string()
|
|
@@ -70,11 +70,9 @@ export const resolveGhidraExtensions = async (config, target, platform, signal)
|
|
|
70
70
|
const configured = adapter.configuredPath(config);
|
|
71
71
|
if (configured === undefined)
|
|
72
72
|
continue;
|
|
73
|
-
const
|
|
74
|
-
if (
|
|
75
|
-
return err(
|
|
76
|
-
diagnostics: { extension: adapter.id, reason, path: configured },
|
|
77
|
-
}));
|
|
73
|
+
const refusal = adapter.unsupportedReason(target, platform);
|
|
74
|
+
if (refusal !== null)
|
|
75
|
+
return err(extensionRefusalError(refusal, target));
|
|
78
76
|
try {
|
|
79
77
|
const path = await realpath(configured);
|
|
80
78
|
const bytes = await readJar(path);
|
|
@@ -115,12 +113,21 @@ export const validateGhidraExtensionProfile = (extensions, config, target, platf
|
|
|
115
113
|
adapter.entryClass !== extension.entry_class ||
|
|
116
114
|
adapter.configuredPath(config) !== extension.configured_path)
|
|
117
115
|
return `Ghidra extension profile lacks matching explicit local configuration: ${extension.id}`;
|
|
118
|
-
const
|
|
119
|
-
if (
|
|
120
|
-
return reason;
|
|
116
|
+
const refusal = adapter.unsupportedReason(target, platform);
|
|
117
|
+
if (refusal !== null)
|
|
118
|
+
return refusal.reason;
|
|
121
119
|
}
|
|
122
120
|
return null;
|
|
123
121
|
};
|
|
122
|
+
/**
|
|
123
|
+
* A deliberate host or target refusal is not an execution failure: retrying
|
|
124
|
+
* cannot change it, and its reason already names the remedy.
|
|
125
|
+
*/
|
|
126
|
+
const extensionRefusalError = (refusal, target) => refusal.constraint === "host"
|
|
127
|
+
? new AnalysisCapabilityUnavailableError("ghidra", "resolve_analysis_profile", refusal.reason, { userMessage: refusal.reason })
|
|
128
|
+
: new AnalysisUnsupportedTargetError("resolve_analysis_profile", target.path, refusal.reason,
|
|
129
|
+
// The reason names the workflows that remain available.
|
|
130
|
+
{ remediationAction: refusal.reason });
|
|
124
131
|
/** Snapshot committed extension bytes into the private runtime before Java loads them. */
|
|
125
132
|
export const snapshotGhidraExtensions = async (extensions, runtimeRoot) => {
|
|
126
133
|
if (extensions.length === 0)
|
|
@@ -5,11 +5,17 @@ export const nativeAotAdapter = {
|
|
|
5
5
|
entryClass: "rea.extensions.nativeaot.NativeAotExtension",
|
|
6
6
|
configuredPath: (config) => config.ghidraNativeAotJar,
|
|
7
7
|
unsupportedReason: (target, platform) => platform !== "linux"
|
|
8
|
-
?
|
|
8
|
+
? {
|
|
9
|
+
constraint: "host",
|
|
10
|
+
reason: "NativeAOT recovery is verified on Linux only; omit REA_GHIDRA_NATIVEAOT_JAR for ordinary native analysis.",
|
|
11
|
+
}
|
|
9
12
|
: !["elf", "pe"].includes(target.format) ||
|
|
10
13
|
target.architecture !== "x86_64" ||
|
|
11
14
|
target.managed === true
|
|
12
|
-
?
|
|
15
|
+
? {
|
|
16
|
+
constraint: "target",
|
|
17
|
+
reason: "NativeAOT recovery requires an x86-64 ELF or native PE target on Linux; PE/CLI and ReadyToRun assemblies use inspect_managed_artifact; omit REA_GHIDRA_NATIVEAOT_JAR for ordinary native analysis.",
|
|
18
|
+
}
|
|
13
19
|
: null,
|
|
14
20
|
validate: validateNativeAotReport,
|
|
15
21
|
limitations: [
|
|
@@ -9,9 +9,8 @@ import { execFileOutput } from "../process/ExecFileOutput.js";
|
|
|
9
9
|
import { spawnOwnedProviderProcess, } from "../process/ProviderProcess.js";
|
|
10
10
|
import { waitForAbortableDelay } from "../process/ProviderDeadline.js";
|
|
11
11
|
import { selectLinuxPrivateDisplayStrategy, } from "./LinuxPrivateDisplayProbe.js";
|
|
12
|
-
import writeFileAtomic from "write-file-atomic";
|
|
13
12
|
import { prepareHopperMachOImage, } from "./HopperMachOImage.js";
|
|
14
|
-
import { acquireHopperTargetLease } from "./HopperTargetLease.js";
|
|
13
|
+
import { acquireHopperTargetLease, acquireLinuxHopperApplicationLease, } from "./HopperTargetLease.js";
|
|
15
14
|
const execFileAsync = promisify(execFile);
|
|
16
15
|
const HOPPER_BACKGROUND_STARTUP_MS = 5_000;
|
|
17
16
|
/**
|
|
@@ -36,7 +35,7 @@ export class HopperApplicationLauncher {
|
|
|
36
35
|
this.dependencies = dependencies;
|
|
37
36
|
}
|
|
38
37
|
async launch(session, options = {}) {
|
|
39
|
-
const leaseResult = await this.#
|
|
38
|
+
const leaseResult = await this.#acquireLaunchLease(session.runId);
|
|
40
39
|
if (!leaseResult.ok)
|
|
41
40
|
return leaseResult;
|
|
42
41
|
const lease = leaseResult.value;
|
|
@@ -86,7 +85,7 @@ export class HopperApplicationLauncher {
|
|
|
86
85
|
const display = await this.#privateDisplay(signal);
|
|
87
86
|
if (!display.ok)
|
|
88
87
|
return err(display.error);
|
|
89
|
-
const prepared = await prepareHopperApplication(this.options.launcherPath, signal);
|
|
88
|
+
const prepared = await prepareHopperApplication(this.options.launcherPath, this.options.environment, signal);
|
|
90
89
|
if (!prepared)
|
|
91
90
|
return err(new HopperCancelledError());
|
|
92
91
|
const linuxDemo = linuxDemoLaunch(this.options, session, argumentsForTarget, display.strategy);
|
|
@@ -101,22 +100,7 @@ export class HopperApplicationLauncher {
|
|
|
101
100
|
});
|
|
102
101
|
if (started === null)
|
|
103
102
|
return err(new HopperCancelledError());
|
|
104
|
-
const cleanup = () => cleanupOwnedProcessGroup(started.ownership)
|
|
105
|
-
const ownership = {
|
|
106
|
-
run_id: session.runId,
|
|
107
|
-
pid: started.ownership.leaderPid,
|
|
108
|
-
process_group_id: started.ownership.leaderPid,
|
|
109
|
-
parent_pid: process.pid,
|
|
110
|
-
launcher: linuxDemo?.command ?? this.options.launcherPath,
|
|
111
|
-
created_at: new Date().toISOString(),
|
|
112
|
-
};
|
|
113
|
-
try {
|
|
114
|
-
await writeFileAtomic(join(session.directory, "ownership.json"), `${JSON.stringify(ownership)}\n`, { encoding: "utf8", mode: 0o600 });
|
|
115
|
-
}
|
|
116
|
-
catch (cause) {
|
|
117
|
-
await cleanupOwnedProcessGroup(started.ownership);
|
|
118
|
-
return err(new HopperStartError({ cause }));
|
|
119
|
-
}
|
|
103
|
+
const cleanup = () => cleanupOwnedProcessGroup(started.ownership);
|
|
120
104
|
const ownedLauncher = {
|
|
121
105
|
...(this.options.preparedImage === undefined
|
|
122
106
|
? {}
|
|
@@ -125,6 +109,8 @@ export class HopperApplicationLauncher {
|
|
|
125
109
|
ownsProcessLifetime: true,
|
|
126
110
|
ownership: started.ownership,
|
|
127
111
|
cleanup,
|
|
112
|
+
launcherCommand: linuxDemo?.command ?? this.options.launcherPath,
|
|
113
|
+
...(lease === undefined ? {} : { releaseLease: () => lease.release() }),
|
|
128
114
|
};
|
|
129
115
|
return ownsProcessLifetime
|
|
130
116
|
? ok({
|
|
@@ -142,26 +128,35 @@ export class HopperApplicationLauncher {
|
|
|
142
128
|
return err(hopperLaunchFailure(cause, signal));
|
|
143
129
|
}
|
|
144
130
|
}
|
|
145
|
-
async #
|
|
146
|
-
|
|
131
|
+
async #acquireLaunchLease(runId) {
|
|
132
|
+
const platform = this.dependencies.platform ?? process.platform;
|
|
133
|
+
const applicationLease = platform === "linux" && usesLinuxDemo(this.options);
|
|
134
|
+
if (!applicationLease && platform !== "darwin")
|
|
147
135
|
return ok(undefined);
|
|
148
136
|
try {
|
|
149
|
-
const acquisition =
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
137
|
+
const acquisition = applicationLease
|
|
138
|
+
? await (this.dependencies.acquireApplicationLease ??
|
|
139
|
+
acquireLinuxHopperApplicationLease)({ runId })
|
|
140
|
+
: await (this.dependencies.acquireTargetLease ?? acquireHopperTargetLease)({
|
|
141
|
+
targetPath: this.options.targetPath,
|
|
142
|
+
targetKind: this.options.targetKind,
|
|
143
|
+
loaderArgs: this.options.loaderArgs,
|
|
144
|
+
runId,
|
|
145
|
+
});
|
|
155
146
|
if (!acquisition.acquired)
|
|
156
147
|
return err(new HopperStartError({
|
|
157
148
|
ownerRunId: acquisition.owner.runId,
|
|
158
|
-
userMessage:
|
|
159
|
-
|
|
149
|
+
userMessage: applicationLease
|
|
150
|
+
? `Linux Hopper is already active in REA session ${acquisition.owner.runId}; it cannot open ${this.options.targetPath} in another session. This build forwards new launches to the existing application. Use the owning REA session to switch targets, or close it before retrying.`
|
|
151
|
+
: `This Hopper target is already open in REA session ${acquisition.owner.runId}. ` +
|
|
152
|
+
"Use that REA session or close it before opening this target again.",
|
|
160
153
|
}));
|
|
161
154
|
return ok(acquisition.lease);
|
|
162
155
|
}
|
|
163
156
|
catch (cause) {
|
|
164
|
-
return err(
|
|
157
|
+
return err(cause instanceof HopperStartError
|
|
158
|
+
? cause
|
|
159
|
+
: new HopperStartError({ cause }));
|
|
165
160
|
}
|
|
166
161
|
}
|
|
167
162
|
async #writeBootstrap(session, ownsProcessLifetime, loadedPath) {
|
|
@@ -181,6 +176,7 @@ export class HopperApplicationLauncher {
|
|
|
181
176
|
const selection = await (this.dependencies.selectPrivateDisplay ??
|
|
182
177
|
selectLinuxPrivateDisplayStrategy)({
|
|
183
178
|
helperPath: this.options.demoHelperPath,
|
|
179
|
+
environment: this.options.environment,
|
|
184
180
|
...(signal === undefined ? {} : { signal }),
|
|
185
181
|
});
|
|
186
182
|
if (signal?.aborted === true)
|
|
@@ -209,6 +205,7 @@ const launchHopperProcess = async (input) => {
|
|
|
209
205
|
arguments: arguments_,
|
|
210
206
|
runId: input.session.runId,
|
|
211
207
|
expectedCommand: ownershipCommand,
|
|
208
|
+
hostEnvironment: input.options.environment,
|
|
212
209
|
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
213
210
|
});
|
|
214
211
|
if (input.linuxDemo !== undefined)
|
|
@@ -217,6 +214,7 @@ const launchHopperProcess = async (input) => {
|
|
|
217
214
|
arguments: input.linuxDemo.args,
|
|
218
215
|
runId: input.session.runId,
|
|
219
216
|
expectedCommand: ownershipCommand,
|
|
217
|
+
hostEnvironment: input.options.environment,
|
|
220
218
|
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
221
219
|
});
|
|
222
220
|
return spawn(input.argumentsForTarget);
|
|
@@ -262,21 +260,16 @@ const hopperLaunchFailure = (cause, signal) => signal?.aborted === true
|
|
|
262
260
|
: new HopperStartError({ cause });
|
|
263
261
|
/** Select the version-pinned adapter from the caller's explicit launch mode. */
|
|
264
262
|
export const usesLinuxDemo = (options) => options.launchMode === "verified_linux_demo";
|
|
265
|
-
const prepareHopperApplication = async (launcherPath, signal) => {
|
|
263
|
+
const prepareHopperApplication = async (launcherPath, environment, signal) => {
|
|
266
264
|
const appBundle = hopperApplicationBundle(launcherPath);
|
|
267
265
|
if (appBundle === undefined)
|
|
268
266
|
return signal?.aborted !== true;
|
|
269
267
|
const executablePath = join(appBundle, "Contents/MacOS/Hopper Disassembler");
|
|
270
|
-
if (await processIsRunning(executablePath))
|
|
268
|
+
if (await processIsRunning(executablePath, environment))
|
|
271
269
|
return signal?.aborted !== true;
|
|
272
270
|
// This reduces activation when Hopper is cold, but the vendor launcher that
|
|
273
271
|
// follows may still activate its window. See HopperApplicationLauncher.
|
|
274
|
-
await execFileAsync("/usr/bin/open", [
|
|
275
|
-
"--hide",
|
|
276
|
-
"--background",
|
|
277
|
-
"-a",
|
|
278
|
-
appBundle,
|
|
279
|
-
]);
|
|
272
|
+
await execFileAsync("/usr/bin/open", ["--hide", "--background", "-a", appBundle], { env: environment });
|
|
280
273
|
return ((await waitForAbortableDelay(HOPPER_BACKGROUND_STARTUP_MS, signal)) ===
|
|
281
274
|
"elapsed");
|
|
282
275
|
};
|
|
@@ -286,13 +279,9 @@ const hopperApplicationBundle = (launcherPath) => {
|
|
|
286
279
|
const candidate = dirname(dirname(dirname(launcherPath)));
|
|
287
280
|
return extname(candidate) === ".app" ? candidate : undefined;
|
|
288
281
|
};
|
|
289
|
-
const processIsRunning = async (executablePath) => {
|
|
282
|
+
const processIsRunning = async (executablePath, environment) => {
|
|
290
283
|
try {
|
|
291
|
-
const processes = await execFileOutput("/bin/ps", [
|
|
292
|
-
"-ax",
|
|
293
|
-
"-o",
|
|
294
|
-
"command=",
|
|
295
|
-
]);
|
|
284
|
+
const processes = await execFileOutput("/bin/ps", ["-ax", "-o", "command="], { env: environment });
|
|
296
285
|
return processes.stdout
|
|
297
286
|
.split("\n")
|
|
298
287
|
.some((command) => command.trim() === executablePath);
|
|
@@ -10,7 +10,7 @@ import { resolveHopperMachOImage, } from "./HopperMachOImage.js";
|
|
|
10
10
|
/** Resolve Hopper open semantics without placing its CLI flags in BinaryTarget. */
|
|
11
11
|
export const resolveHopperAnalysisProfile = async (target, options) => {
|
|
12
12
|
if (target.kind !== "executable" && target.kind !== "database")
|
|
13
|
-
return ok({ profile: null
|
|
13
|
+
return ok({ profile: null });
|
|
14
14
|
let machoContainer;
|
|
15
15
|
if (target.kind === "executable" && target.format === "mach-o") {
|
|
16
16
|
const header = await readMachoMagic(target.path, options.signal);
|
|
@@ -37,12 +37,11 @@ export const resolveHopperAnalysisProfile = async (target, options) => {
|
|
|
37
37
|
const loaderArgs = options.loaderArgsOverride.length === 0
|
|
38
38
|
? derived.value
|
|
39
39
|
: [...options.loaderArgsOverride];
|
|
40
|
-
const compatibility = { loaderArgs: [...loaderArgs] };
|
|
41
40
|
const launcherDigest = await sha256File(options.launcherPath, options.signal);
|
|
42
41
|
if (!launcherDigest.ok)
|
|
43
42
|
return launcherDigest;
|
|
44
43
|
if (launcherDigest.value === undefined)
|
|
45
|
-
return ok({ profile: null
|
|
44
|
+
return ok({ profile: null });
|
|
46
45
|
const provider = {
|
|
47
46
|
id: options.provider.id,
|
|
48
47
|
name: options.provider.name,
|
|
@@ -66,13 +65,9 @@ export const resolveHopperAnalysisProfile = async (target, options) => {
|
|
|
66
65
|
source: options.loaderArgsOverride.length === 0
|
|
67
66
|
? "derived"
|
|
68
67
|
: "configured_override",
|
|
69
|
-
|
|
70
|
-
arguments_sha256: createHash("sha256")
|
|
71
|
-
.update(JSON.stringify(loaderArgs))
|
|
72
|
-
.digest("hex"),
|
|
68
|
+
arguments: [...loaderArgs],
|
|
73
69
|
},
|
|
74
70
|
}),
|
|
75
|
-
compatibility,
|
|
76
71
|
});
|
|
77
72
|
};
|
|
78
73
|
/** Derive Hopper's complete non-interactive CLI loader selection. */
|
|
@@ -9,33 +9,54 @@ export const cleanupHopperSession = async (input) => {
|
|
|
9
9
|
issues: [],
|
|
10
10
|
resources: new Set(),
|
|
11
11
|
cleanupResult: undefined,
|
|
12
|
-
|
|
12
|
+
processStopped: input.resources.processSupervisor === undefined,
|
|
13
13
|
};
|
|
14
|
-
await report(input.progress, 0, input.retainDocument &&
|
|
14
|
+
await report(input.progress, 0, input.retainDocument &&
|
|
15
|
+
input.resources.launch?.preparedImagePath === undefined
|
|
15
16
|
? "detaching REA from the Hopper document"
|
|
16
17
|
: "requesting Hopper document shutdown");
|
|
17
18
|
await requestShutdown(input, state);
|
|
18
19
|
await report(input.progress, 0.35, "releasing Hopper bridge transport");
|
|
19
|
-
|
|
20
|
+
if (input.resources.shutdownConfirmed ||
|
|
21
|
+
input.resources.launch?.providerLifetime !== "external-application")
|
|
22
|
+
input.releaseTransport(input.socket);
|
|
20
23
|
await stopProcess(input, state);
|
|
21
24
|
recordUnconfirmedDocument(input, state);
|
|
22
25
|
await report(input.progress, 0.75, "removing Hopper private runtime files");
|
|
23
|
-
if (input.
|
|
24
|
-
!state.
|
|
25
|
-
|
|
26
|
+
if (input.resources.runtimeRoot !== undefined &&
|
|
27
|
+
(!state.processStopped ||
|
|
28
|
+
(!input.resources.shutdownConfirmed &&
|
|
29
|
+
(input.resources.launch?.preparedImagePath !== undefined ||
|
|
30
|
+
input.resources.launch?.providerLifetime === "external-application")))) {
|
|
31
|
+
const resource = input.resources.runtimeRoot.path;
|
|
26
32
|
state.resources.add(resource);
|
|
27
33
|
state.issues.push({
|
|
28
34
|
resource,
|
|
29
|
-
reason: "
|
|
35
|
+
reason: "Private runtime retained because process or native document closure was not confirmed",
|
|
30
36
|
});
|
|
31
37
|
}
|
|
32
38
|
else {
|
|
33
|
-
await closeRuntimeRoot(input
|
|
39
|
+
await closeRuntimeRoot(input, state);
|
|
40
|
+
}
|
|
41
|
+
if (state.processStopped && input.resources.shutdownConfirmed) {
|
|
42
|
+
const launch = input.resources.launch;
|
|
43
|
+
try {
|
|
44
|
+
await launch?.releaseLease?.();
|
|
45
|
+
input.resources.launch = undefined;
|
|
46
|
+
}
|
|
47
|
+
catch (cause) {
|
|
48
|
+
state.resources.add("hopper-lease");
|
|
49
|
+
state.issues.push({
|
|
50
|
+
resource: "hopper-lease",
|
|
51
|
+
reason: cause instanceof Error ? cause.message : String(cause),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
34
54
|
}
|
|
35
55
|
return cleanupOutcome(input, state);
|
|
36
56
|
};
|
|
37
57
|
const requestShutdown = async (input, state) => {
|
|
38
|
-
if (input.
|
|
58
|
+
if (input.resources.shutdownConfirmed ||
|
|
59
|
+
input.socket === undefined ||
|
|
39
60
|
input.socket.destroyed ||
|
|
40
61
|
input.activeRequest !== null) {
|
|
41
62
|
if (input.activeRequest !== null)
|
|
@@ -45,8 +66,9 @@ const requestShutdown = async (input, state) => {
|
|
|
45
66
|
}, "Hopper shutdown skipped because a bridge operation remained active");
|
|
46
67
|
return;
|
|
47
68
|
}
|
|
48
|
-
const method = (input.retainDocument &&
|
|
49
|
-
input.launch?.
|
|
69
|
+
const method = (input.retainDocument &&
|
|
70
|
+
input.resources.launch?.preparedImagePath === undefined) ||
|
|
71
|
+
input.resources.launch?.shutdownMode === "process-cleanup"
|
|
50
72
|
? "shutdown"
|
|
51
73
|
: "shutdown_document";
|
|
52
74
|
const shutdown = await input
|
|
@@ -54,22 +76,19 @@ const requestShutdown = async (input, state) => {
|
|
|
54
76
|
.catch((cause) => err(shutdownRequestFailure(method, cause)));
|
|
55
77
|
if (shutdown.ok &&
|
|
56
78
|
isHopperCleanupRequired(shutdown.value) &&
|
|
57
|
-
input.launch?.shutdownMode === "process-cleanup") {
|
|
58
|
-
state.cleanupResult = await input.launch
|
|
79
|
+
input.resources.launch?.shutdownMode === "process-cleanup") {
|
|
80
|
+
state.cleanupResult = await input.resources.launch
|
|
59
81
|
.cleanup()
|
|
60
82
|
.catch(providerCleanupFailure);
|
|
61
83
|
if (!state.cleanupResult.cleaned) {
|
|
62
|
-
|
|
63
|
-
state.cleanupResult = await input.launch
|
|
64
|
-
.cleanup()
|
|
65
|
-
.catch(providerCleanupFailure);
|
|
84
|
+
input.resources.shutdownConfirmed = await fallbackDocumentShutdown(input);
|
|
66
85
|
}
|
|
67
86
|
}
|
|
68
87
|
else if (shutdown.ok) {
|
|
69
|
-
|
|
88
|
+
input.resources.shutdownConfirmed = isHopperShutdownAcknowledgement(shutdown.value);
|
|
70
89
|
}
|
|
71
90
|
if (!shutdown.ok ||
|
|
72
|
-
(!
|
|
91
|
+
(!input.resources.shutdownConfirmed && state.cleanupResult === undefined))
|
|
73
92
|
input.logger.warn({
|
|
74
93
|
status: shutdown.ok ? "invalid-acknowledgement" : "failed",
|
|
75
94
|
...(shutdown.ok ? {} : shutdownFailureDetails(shutdown.error)),
|
|
@@ -125,7 +144,7 @@ const describeFailureCause = (cause) => {
|
|
|
125
144
|
return { type: typeof cause };
|
|
126
145
|
};
|
|
127
146
|
const stopProcess = async (input, state) => {
|
|
128
|
-
const supervisor = input.processSupervisor;
|
|
147
|
+
const supervisor = input.resources.processSupervisor;
|
|
129
148
|
if (supervisor === undefined)
|
|
130
149
|
return;
|
|
131
150
|
const stopped = await supervisor.stop(state.cleanupResult === undefined
|
|
@@ -141,9 +160,11 @@ const stopProcess = async (input, state) => {
|
|
|
141
160
|
}
|
|
142
161
|
input.logger.info(diagnostic, "Owned Hopper launcher shutdown completed");
|
|
143
162
|
if (stopped.status !== "incomplete") {
|
|
144
|
-
if (input.launch?.shutdownMode === "process-cleanup" &&
|
|
163
|
+
if (input.resources.launch?.shutdownMode === "process-cleanup" &&
|
|
145
164
|
stopped.status !== "not-owned")
|
|
146
|
-
|
|
165
|
+
input.resources.shutdownConfirmed = true;
|
|
166
|
+
state.processStopped = true;
|
|
167
|
+
input.resources.processSupervisor = undefined;
|
|
147
168
|
return;
|
|
148
169
|
}
|
|
149
170
|
const processGroupId = supervisor.launch.ownership?.processGroupId;
|
|
@@ -155,8 +176,14 @@ const stopProcess = async (input, state) => {
|
|
|
155
176
|
input.logger.warn({ reason: stopped.reason }, "Owned launcher cleanup failed closed");
|
|
156
177
|
};
|
|
157
178
|
const recordUnconfirmedDocument = (input, state) => {
|
|
158
|
-
if (
|
|
159
|
-
state.
|
|
179
|
+
if (input.socket === undefined &&
|
|
180
|
+
state.processStopped &&
|
|
181
|
+
input.resources.launch?.providerLifetime === "launcher-process") {
|
|
182
|
+
// Startup never connected a document; the verified provider lifetime ended.
|
|
183
|
+
input.resources.shutdownConfirmed = true;
|
|
184
|
+
}
|
|
185
|
+
if ((input.socket === undefined && input.resources.launch === undefined) ||
|
|
186
|
+
input.resources.shutdownConfirmed)
|
|
160
187
|
return;
|
|
161
188
|
state.resources.add("hopper-document");
|
|
162
189
|
state.issues.push({
|
|
@@ -166,9 +193,11 @@ const recordUnconfirmedDocument = (input, state) => {
|
|
|
166
193
|
: `bridge operation ${input.activeRequest.operation} remained active after caller ${input.activeRequest.callerState}`,
|
|
167
194
|
});
|
|
168
195
|
};
|
|
169
|
-
const closeRuntimeRoot = async (
|
|
196
|
+
const closeRuntimeRoot = async (input, state) => {
|
|
197
|
+
const runtimeRoot = input.resources.runtimeRoot;
|
|
170
198
|
try {
|
|
171
199
|
await runtimeRoot?.close();
|
|
200
|
+
input.resources.runtimeRoot = undefined;
|
|
172
201
|
}
|
|
173
202
|
catch (cause) {
|
|
174
203
|
const resource = runtimeRoot?.path ?? "hopper-runtime-root";
|
|
@@ -186,9 +215,9 @@ const cleanupOutcome = (input, state) => {
|
|
|
186
215
|
return ok(null);
|
|
187
216
|
return err(new ProviderCleanupError("hopper", [...state.resources], {
|
|
188
217
|
issues: cleanupIssueDetails(state.issues),
|
|
189
|
-
...(input.runtimeRoot === undefined
|
|
218
|
+
...(input.resources.runtimeRoot === undefined
|
|
190
219
|
? {}
|
|
191
|
-
: { runtime_root: input.runtimeRoot.path }),
|
|
220
|
+
: { runtime_root: input.resources.runtimeRoot.path }),
|
|
192
221
|
...(input.activeRequest === null
|
|
193
222
|
? {}
|
|
194
223
|
: { active_request: activityDetails(input.activeRequest) }),
|