rea-agents 6.1.0 → 6.3.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 +24 -24
- package/bridge/ghidra/ReaGhidraBridge.java +32 -4
- package/bridge/hopper_bridge.py +8 -1
- package/dist/android/JadxConfiguration.js +87 -7
- package/dist/android/JadxMcpTransport.js +14 -2
- package/dist/android/JadxProvider.js +64 -36
- package/dist/android/JadxSession.js +51 -9
- package/dist/application/BinaryTargetResolver.js +68 -20
- package/dist/application/BrowserEvidence.js +3 -8
- package/dist/application/BrowserScenarioEvidence.js +4 -20
- package/dist/application/CapabilityInventory.js +43 -9
- package/dist/application/ClientConfigurationDocument.js +97 -25
- package/dist/application/ClientRegistrationStatus.js +19 -6
- package/dist/application/DirectAnalysis.js +41 -20
- package/dist/application/DirectAnalysisCleanup.js +71 -0
- package/dist/application/DirectAnalysisStatus.js +3 -7
- package/dist/application/Doctor.js +40 -53
- package/dist/application/DoctorDiagnostics.js +2 -3
- package/dist/application/EnhancedTools.js +51 -6
- package/dist/application/EvidenceBundleFiles.js +8 -3
- package/dist/application/InvestigationProviders.js +13 -5
- package/dist/application/JsonFiles.js +56 -23
- package/dist/application/LinuxHopper.js +11 -7
- package/dist/application/MacHopper.js +15 -18
- package/dist/application/RealHopperAssertions.js +0 -11
- package/dist/application/ReconstructionObligationCandidates.js +10 -3
- package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
- package/dist/application/ReferenceSourceImportEntries.js +1 -1
- package/dist/application/RegularFileRead.js +17 -0
- package/dist/application/Setup.js +26 -23
- package/dist/application/SetupClientConfiguration.js +18 -7
- package/dist/application/SetupHost.js +20 -29
- package/dist/application/SetupPlan.js +24 -20
- package/dist/application/SetupSkill.js +57 -8
- package/dist/application/SupportedClients.js +43 -0
- package/dist/application/Uninstall.js +98 -30
- package/dist/application/UpdateMaintenance.js +13 -7
- package/dist/application/UpdateRuntime.js +12 -12
- package/dist/application/Utf8JsonInput.js +64 -0
- package/dist/application/WebScriptExportService.js +38 -5
- 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/android/AndroidAnalysisService.js +1 -1
- 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 +13 -10
- package/dist/application/binary/BinarySession.js +86 -29
- package/dist/application/binary/BinarySessionComposition.js +1 -3
- package/dist/application/binary/BinarySessionExecution.js +3 -5
- package/dist/application/binary/BinarySessionOpen.js +10 -2
- 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 +10 -14
- package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
- package/dist/application/javascript/ElectronBoundaryGraphNative.js +5 -1
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +3 -6
- package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
- package/dist/application/javascript/JavaScriptApplicationService.js +7 -1
- package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -9
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +19 -27
- 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 +46 -29
- package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +86 -27
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +52 -9
- package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +1 -0
- package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
- package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -18
- package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -3
- package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +4 -5
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +8 -6
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +7 -5
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +3 -4
- package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +3 -7
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +76 -47
- package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +3 -4
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +51 -25
- package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
- package/dist/application/managed/ManagedMemberComparisonService.js +2 -1
- package/dist/application/managed/ManagedNativeVerificationService.js +2 -1
- package/dist/application/native/NativeCallRoutes.js +2 -4
- package/dist/application/process/ProcessCli.js +11 -11
- package/dist/application/process/ProcessEvidence.js +0 -1
- package/dist/artifacts/ArtifactProvider.js +53 -30
- package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
- package/dist/artifacts/ArtifactReader.js +31 -0
- package/dist/artifacts/AsarArtifactReader.js +81 -17
- package/dist/artifacts/DirectoryArtifactReader.js +2 -1
- package/dist/artifacts/MachOSliceArtifactReader.js +9 -2
- package/dist/artifacts/NativeDmgArtifactReader.js +207 -77
- package/dist/artifacts/NativeDmgOwnership.js +109 -0
- 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 +68 -42
- package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
- package/dist/artifacts/extraction/ArtifactExtraction.js +104 -29
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +71 -66
- package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
- package/dist/artifacts/inventory/classify.js +33 -14
- package/dist/artifacts/inventory/hashStableRootArtifact.js +37 -0
- package/dist/artifacts/inventory/reader.js +3 -3
- package/dist/artifacts/inventory/scanCanonical.js +64 -34
- package/dist/artifacts/inventory/scanReader.js +12 -20
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +65 -27
- package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
- package/dist/browser/CdpBrowserProvider.js +6 -6
- package/dist/browser/CdpCaptureEventHandlers.js +2 -4
- package/dist/browser/CdpCaptureEvents.js +0 -1
- package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
- package/dist/browser/CdpCaptureValues.js +20 -0
- package/dist/browser/CdpElectronInspection.js +2 -2
- package/dist/browser/CdpElectronProvider.js +4 -5
- package/dist/browser/CdpElectronScriptEvents.js +2 -8
- package/dist/browser/CdpElectronScripts.js +4 -5
- package/dist/browser/CdpPageCaptureScripts.js +2 -3
- package/dist/browser/CdpSafeMetadata.js +10 -10
- package/dist/browser/CdpWebMcpDiscovery.js +16 -13
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +64 -49
- 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 +269 -66
- package/dist/browser/PlaywrightScenarioEvents.js +1 -1
- package/dist/browser/PlaywrightScenarioSession.js +41 -32
- package/dist/browser/WebSourceMapFetcher.js +32 -6
- package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
- 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 +37 -28
- package/dist/cli/coreNativeCommands.js +9 -10
- package/dist/cli/electronCommands.js +12 -13
- package/dist/cli/interactiveSetup.js +6 -6
- package/dist/cli/javascriptApplicationAnalysis.js +2 -12
- package/dist/cli/jsonOutput.js +3 -2
- 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/streamedJsonOutput.js +83 -4
- package/dist/cli/utilityCommands.js +10 -12
- package/dist/cli.js +19 -8
- package/dist/cliBrowserScenarioCommands.js +2 -2
- package/dist/cliCommandNames.js +1 -0
- package/dist/cliJsonFile.js +179 -0
- package/dist/cliJsonInput.js +60 -33
- package/dist/cliObservationOptions.js +4 -0
- package/dist/cliOutput.js +0 -38
- package/dist/composition/auxiliaryAnalysisProviders.js +30 -25
- package/dist/composition/binary.js +9 -9
- package/dist/composition/browserScenario.js +2 -1
- package/dist/composition/directAnalysis.js +20 -14
- 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 +7 -7
- 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/errorSchemas.js +3 -1
- package/dist/contracts/evm/evmToolContracts.js +1 -1
- package/dist/contracts/functionComparisonExample.js +8 -0
- package/dist/contracts/functionWorkflowToolContracts.js +1 -1
- package/dist/contracts/inputSchemaPresentation.js +181 -0
- package/dist/contracts/investigationExamples.js +4 -3
- package/dist/contracts/javascript/electronToolContracts.js +3 -2
- package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -22
- package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +248 -0
- package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
- package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
- package/dist/contracts/managed/managedToolContracts.js +8 -12
- package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
- package/dist/contracts/mobileApplicationGraphExamples.js +8 -8
- 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/sessionLifecycleInputs.js +4 -3
- package/dist/contracts/sessionStatusContract.js +3 -2
- package/dist/contracts/sessionToolContracts.js +17 -4
- package/dist/contracts/sessionToolSchemas.js +4 -16
- package/dist/contracts/toolContracts.js +2 -0
- package/dist/contracts/toolEffects.js +1 -0
- package/dist/contracts/toolOutputSchemaGroups.js +138 -94
- package/dist/contracts/toolOutputSchemaPrimitives.js +13 -26
- 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/analysisErrorBase.js +5 -0
- package/dist/domain/analysisErrorCore.js +3 -0
- package/dist/domain/analysisErrorPresentation.js +22 -5
- package/dist/domain/analysisErrorProjection.js +24 -5
- package/dist/domain/analysisSnapshot.js +31 -31
- package/dist/domain/analysisView/analysisView.js +241 -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/android/androidPartialObservation.js +36 -0
- 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 +17 -4
- package/dist/domain/artifactIdentity.js +8 -8
- package/dist/domain/artifactInspection.js +8 -8
- 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/browserCompleteness.js +3 -2
- 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/browserScenarioCaptureValues.js +2 -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/browserScenarioNormalization.js +3 -3
- package/dist/domain/browserScenarioValues.js +6 -6
- package/dist/domain/callPath.js +15 -18
- package/dist/domain/callPathSchemas.js +2 -2
- package/dist/domain/canonicalDigest.js +7 -1
- package/dist/domain/canonicalOrdering.js +1 -13
- package/dist/domain/changedBehavior.js +5 -6
- package/dist/domain/comparisonSemantics.js +0 -5
- package/dist/domain/completionLedgerGeneration.js +2 -1
- package/dist/domain/configurationErrors.js +12 -0
- package/dist/domain/conformancePackage.js +4 -3
- package/dist/domain/digests.js +0 -3
- package/dist/domain/evidence.js +19 -40
- package/dist/domain/evidenceBundle.js +58 -42
- package/dist/domain/evidenceCompletionLedger.js +2 -1
- package/dist/domain/firmware/firmwareAnalysis.js +4 -3
- package/dist/domain/functionComparison.js +6 -6
- package/dist/domain/functionComparisonDimensions.js +120 -87
- package/dist/domain/functionComparisonNormalization.js +26 -36
- package/dist/domain/functionComparisonResults.js +3 -6
- package/dist/domain/functionComparisonSchemas.js +2 -8
- package/dist/domain/functionDossierEvidence.js +4 -38
- package/dist/domain/hopperValues.js +11 -15
- package/dist/domain/javascript/electronActiveObservation.js +29 -71
- package/dist/domain/javascript/electronObservation.js +14 -3
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -11
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -2
- package/dist/domain/javascript/electronStaticAnalysisNative.js +7 -4
- package/dist/domain/javascript/electronStaticAnalysisValues.js +8 -4
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +3 -1
- package/dist/domain/javascript/javascriptApplicationChangeGraph.js +12 -8
- package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +6 -0
- package/dist/domain/javascript/javascriptApplicationGraph.js +41 -16
- package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
- package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
- package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +50 -36
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -8
- package/dist/domain/javascript/javascriptAstFingerprint.js +2 -2
- package/dist/domain/javascript/javascriptAstValues.js +22 -0
- package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
- package/dist/domain/javascript/javascriptExportShapeComparison.js +10 -3
- package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
- package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +58 -22
- package/dist/domain/javascript/javascriptExportShapeSelection.js +7 -7
- package/dist/domain/javascript/javascriptExportShapeVariants.js +70 -16
- package/dist/domain/javascript/javascriptFeatureSeed.js +25 -3
- package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
- package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
- package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -5
- package/dist/domain/javascript/javascriptNativeHandoff.js +7 -7
- package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
- package/dist/domain/javascript/javascriptRuntimeObservation.js +18 -7
- package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
- package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
- package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +5 -4
- package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +6 -6
- package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -222
- package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
- package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
- package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +7 -7
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +209 -11
- package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
- package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
- package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
- package/dist/domain/javascript/javascriptSemanticChildProcesses.js +4 -3
- package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
- package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
- package/dist/domain/javascript/javascriptSemanticFingerprints.js +2 -2
- package/dist/domain/javascript/javascriptSemanticGraph.js +220 -71
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +19 -1
- package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
- package/dist/domain/javascript/javascriptSemanticIterationSources.js +106 -0
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +515 -74
- package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +44 -36
- package/dist/domain/javascript/javascriptSemanticObjects.js +79 -42
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +8 -14
- package/dist/domain/javascript/javascriptSemanticProjection.js +21 -16
- package/dist/domain/javascript/javascriptSemanticPromises.js +16 -21
- package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +23 -0
- package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
- package/dist/domain/javascript/javascriptSemanticQuery.js +8 -2
- package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +3 -2
- package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
- package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
- package/dist/domain/javascript/javascriptSemanticResourceLimits.js +1 -1
- package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
- package/dist/domain/javascript/javascriptSemanticReturns.js +55 -44
- package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
- package/dist/domain/javascript/javascriptSemanticTraversal.js +6 -1
- package/dist/domain/javascript/javascriptSemanticValues.js +180 -76
- package/dist/domain/javascript/javascriptSourceMapPaths.js +114 -0
- package/dist/domain/javascript/javascriptSourceParser.js +34 -9
- package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -6
- package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +2 -1
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -16
- package/dist/domain/javascript/sourceToBundleComparison.js +19 -8
- package/dist/domain/javascript/sourceToBundleSignals.js +53 -25
- package/dist/domain/jsonSerialization.js +109 -55
- package/dist/domain/jsonShape.js +46 -19
- package/dist/domain/localPath.js +10 -4
- package/dist/domain/managed/managedApplicationGraph.js +10 -6
- package/dist/domain/managed/managedApplicationGraphNodes.js +82 -57
- package/dist/domain/managed/managedArtifact.js +6 -4
- package/dist/domain/managed/managedMemberComparison.js +2 -9
- package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
- 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 +3 -3
- package/dist/domain/native/nativeInstruction.js +7 -0
- package/dist/domain/native/nativeValueFlow.js +5 -11
- package/dist/domain/native/objcSwiftMetadata.js +15 -17
- package/dist/domain/native/recordedCrash.js +2 -3
- package/dist/domain/offsetDateTime.js +17 -0
- package/dist/domain/process/processCapture.js +22 -20
- package/dist/domain/process/processCaptureCoverage.js +70 -0
- package/dist/domain/process/processCaptureExample.js +45 -1
- package/dist/domain/process/processCaptureParsing.js +1 -34
- package/dist/domain/process/processCaptureValidation.js +82 -13
- package/dist/domain/process/processComparison.js +39 -43
- 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 +19 -15
- package/dist/domain/process/processTraceSpecification.js +4 -7
- package/dist/domain/providerAdapterError.js +2 -0
- package/dist/domain/providerCleanupError.js +6 -2
- package/dist/domain/reconstructionCoverage.js +7 -3
- package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
- package/dist/domain/reconstructionReadinessSchemas.js +2 -1
- package/dist/domain/reconstructionUnknowns.js +4 -3
- package/dist/domain/reconstructionVerification.js +6 -5
- package/dist/domain/reconstructionVerificationSchemas.js +2 -1
- package/dist/domain/referenceSourceGraph.js +27 -28
- package/dist/domain/referenceSourceImportParsing.js +34 -45
- package/dist/domain/residualUnknown.js +3 -2
- package/dist/domain/staticRuntimeCorrelation.js +4 -3
- package/dist/domain/stringPatterns.js +6 -0
- package/dist/domain/swiftSymbolClassification.js +66 -0
- package/dist/domain/symbolAnalysis.js +83 -20
- package/dist/domain/unicodeCodePointOrder.js +6 -0
- package/dist/domain/webBundleAnalyzerInspection.js +9 -1
- package/dist/domain/webCaptureDiff.js +71 -30
- package/dist/domain/webCaptureDiffSchemas.js +8 -11
- package/dist/domain/webEventListeners.js +3 -2
- package/dist/domain/webExecution.js +3 -2
- package/dist/domain/webInventory.js +3 -2
- package/dist/domain/webMcpDiscovery.js +4 -3
- package/dist/domain/webRuntime.js +0 -2
- package/dist/domain/webScriptExport.js +2 -2
- package/dist/dotnet/ManagedArtifactInspector.js +2 -19
- package/dist/dotnet/ManagedMemberInspector.js +12 -18
- package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +1 -2
- 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 +13 -12
- package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
- 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/filesystem/RegularFile.js +41 -0
- 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 +105 -36
- 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 +151 -22
- package/dist/ghidra/GhidraJavaLaunch.js +6 -2
- package/dist/ghidra/GhidraLauncher.js +58 -26
- 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 +5 -3
- package/dist/ida/IdaProvider.js +8 -12
- package/dist/ida/IdaSessionClient.js +24 -20
- package/dist/ida/IdaWorkspace.js +12 -13
- package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
- package/dist/inspector/V8InspectorCaptureProjection.js +47 -14
- package/dist/inspector/V8InspectorProvider.js +97 -35
- package/dist/javascript/recovery/WakaruCommand.js +7 -2
- package/dist/javascript/recovery/WakaruExecution.js +5 -2
- package/dist/main/shutdown.js +81 -29
- package/dist/main/startup.js +9 -2
- package/dist/main/transport.js +23 -3
- package/dist/main.js +11 -18
- package/dist/native/AppleMachoSelection.js +16 -6
- package/dist/native/AppleObjcDispatchFacets.js +3 -3
- package/dist/native/AppleObjcProperties.js +17 -7
- package/dist/native/CommandRunner.js +9 -7
- package/dist/native/LldbCallTracer.js +249 -77
- package/dist/native/NativeMacOSProvider.js +32 -17
- package/dist/native/NativeMacOSProviderMetadata.js +1 -2
- 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 +18 -16
- package/dist/process/ProviderProcess.js +1 -3
- package/dist/process/capture/FilesystemSnapshot.js +131 -24
- package/dist/process/capture/ProcessCaptureError.js +13 -0
- package/dist/process/capture/ProcessCaptureLifecycle.js +148 -74
- package/dist/process/capture/ProcessFilesystemEffects.js +51 -6
- package/dist/process/capture/ProcessHarness.js +16 -33
- 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/analysisAdmission.js +8 -0
- package/dist/server/createServer.js +71 -59
- 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 +6 -6
- 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 +4 -4
- 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/registerArtifactTools.js +2 -2
- 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 +8 -7
- package/dist/server/registerElectronTools.js +10 -13
- package/dist/server/registerEnhancedTools.js +82 -77
- package/dist/server/registerEvidenceTools.js +54 -47
- 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/registerManagedTools.js +7 -4
- 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 +32 -41
- 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 +19 -19
- 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 +42 -30
- package/scripts/rea.mjs +3 -6
- package/skills/reverse-engineer-anything/SKILL.md +14 -13
- 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 +18 -0
- package/dist/artifacts/inventory/policy.js +0 -2
- 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/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
- package/dist/main/reload.js +0 -12
- package/dist/main/state.js +0 -3
- package/dist/server/registerNativeTools.js +0 -6
- package/dist/server/sessionToolPolicies.js +0 -2
|
@@ -3,18 +3,22 @@ import { constants, statSync } from "node:fs";
|
|
|
3
3
|
import { open, mkdtemp, rm, stat } from "node:fs/promises";
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
5
|
import { join } from "node:path";
|
|
6
|
-
import {
|
|
6
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
7
|
+
import { digestProcessCommitment, processComparisonContract, processScenarioCommitment, } from "../../domain/process/processScenario.js";
|
|
8
|
+
import { parseProcessCapture } from "../../domain/process/processCaptureParsing.js";
|
|
7
9
|
import { PRODUCT_IDENTITY } from "../../identity.js";
|
|
8
10
|
import { snapshotRoots } from "./FilesystemSnapshot.js";
|
|
9
11
|
import { classifyFilesystemEffects } from "./ProcessFilesystemEffects.js";
|
|
10
12
|
import { cleanupOwnedProcessGroup, verifyNoTokenOwnedProcesses, } from "../ProcessOwnership.js";
|
|
11
13
|
import { observeOwnedProcessGroup, prepareProcessOwnershipInspection, systemProcessOwnershipHost, } from "../ProcessOwnershipObservation.js";
|
|
12
|
-
import { describeProcessCaptureExecutionFailure, ProcessCaptureError, } from "./ProcessCaptureError.js";
|
|
14
|
+
import { describeProcessCaptureExecutionFailure, normalizeCaptureFailure, ProcessCaptureError, } from "./ProcessCaptureError.js";
|
|
13
15
|
import { assertNotCancelled } from "./ProcessScenarioRuntimeValidation.js";
|
|
14
16
|
import { normalizeProcessElapsedTime, normalizeProcessSamples, normalizeProcessText, } from "./ProcessNormalization.js";
|
|
15
17
|
import { PROCESS_PROVIDER } from "../../domain/process/processEvidenceProvider.js";
|
|
16
18
|
import { TerminalRenderer } from "./TerminalRenderer.js";
|
|
19
|
+
import { hasCaptureTruncation, } from "../../domain/process/processCaptureCoverage.js";
|
|
17
20
|
import { scheduleProcessInterval } from "./ProcessTimer.js";
|
|
21
|
+
import { partialProcessCaptureObservationSchema } from "../../domain/process/processCapture.js";
|
|
18
22
|
/** Seed explicit observation availability before capture completion begins. */
|
|
19
23
|
export const createProcessCaptureObservationBuffer = (options) => ({
|
|
20
24
|
target_pid: {
|
|
@@ -39,10 +43,7 @@ export const createProcessCaptureObservationBuffer = (options) => ({
|
|
|
39
43
|
filesystem_snapshots: {
|
|
40
44
|
before: {
|
|
41
45
|
state: "available",
|
|
42
|
-
value:
|
|
43
|
-
files: options.before.files,
|
|
44
|
-
truncated: options.before.truncated,
|
|
45
|
-
},
|
|
46
|
+
value: options.before,
|
|
46
47
|
},
|
|
47
48
|
after: {
|
|
48
49
|
state: "unavailable",
|
|
@@ -92,6 +93,10 @@ export const buildCaptureResult = (options) => {
|
|
|
92
93
|
const sensitiveInputUnknown = "Sensitive scripted input values are redacted from process capture Evidence.";
|
|
93
94
|
const filesystemObservationUnknown = "No filesystem observation paths were selected; filesystem effects remain unknown.";
|
|
94
95
|
const hasFilesystemObservations = options.scenario.filesystem_observation_paths.length > 0;
|
|
96
|
+
const filesystemEffects = classifyFilesystemEffects(options.before, options.after);
|
|
97
|
+
const filesystemUnknowns = [
|
|
98
|
+
...new Set(filesystemEffects.flatMap((effect) => effect.status === "unknown" ? [effect.reason] : [])),
|
|
99
|
+
];
|
|
95
100
|
return {
|
|
96
101
|
manifest: options.manifest,
|
|
97
102
|
normalization: options.scenario.normalization,
|
|
@@ -111,8 +116,9 @@ export const buildCaptureResult = (options) => {
|
|
|
111
116
|
event_journal: options.eventJournal,
|
|
112
117
|
files_before: options.before.files,
|
|
113
118
|
files_after: options.after.files,
|
|
114
|
-
filesystem_effects:
|
|
115
|
-
truncated: options.
|
|
119
|
+
filesystem_effects: filesystemEffects,
|
|
120
|
+
truncated: hasCaptureTruncation(options.truncationDetails),
|
|
121
|
+
truncation_details: options.truncationDetails,
|
|
116
122
|
limitations: [
|
|
117
123
|
"The executable digest is a prelaunch file sample; matching path metadata immediately after spawn does not prove an atomic operating-system image binding.",
|
|
118
124
|
"Process trees are sampled and may omit short-lived descendants.",
|
|
@@ -122,6 +128,8 @@ export const buildCaptureResult = (options) => {
|
|
|
122
128
|
"Filesystem observations are before/after snapshots, not syscall traces.",
|
|
123
129
|
"Inherited host environment variables are not recorded and may affect results.",
|
|
124
130
|
...(!hasFilesystemObservations ? [filesystemObservationUnknown] : []),
|
|
131
|
+
...filesystemUnknowns,
|
|
132
|
+
...captureCoverageUnknowns(options.truncationDetails).map(({ reason }) => reason),
|
|
125
133
|
...(hasSensitiveScriptedInput ? [sensitiveInputUnknown] : []),
|
|
126
134
|
],
|
|
127
135
|
residual_unknowns: [
|
|
@@ -149,12 +157,52 @@ export const buildCaptureResult = (options) => {
|
|
|
149
157
|
},
|
|
150
158
|
]
|
|
151
159
|
: []),
|
|
160
|
+
...filesystemUnknowns.map((reason) => ({
|
|
161
|
+
scope: "filesystem",
|
|
162
|
+
reason,
|
|
163
|
+
})),
|
|
152
164
|
...(hasSensitiveScriptedInput
|
|
153
165
|
? [{ scope: "interaction", reason: sensitiveInputUnknown }]
|
|
154
166
|
: []),
|
|
167
|
+
...captureCoverageUnknowns(options.truncationDetails).filter(({ scope }) => scope !== "terminal"),
|
|
155
168
|
],
|
|
156
169
|
};
|
|
157
170
|
};
|
|
171
|
+
const captureCoverageUnknowns = (details) => {
|
|
172
|
+
const unknowns = [];
|
|
173
|
+
if (details.raw_terminal.observed_frames > details.raw_terminal.retained_frames)
|
|
174
|
+
unknowns.push({
|
|
175
|
+
scope: "terminal",
|
|
176
|
+
reason: "Raw PTY chunks exceeded output_bytes and were omitted; rendered states also lack those inputs. See truncation_details.raw_terminal.",
|
|
177
|
+
});
|
|
178
|
+
if (details.rendered_terminal.observed_frames >
|
|
179
|
+
details.rendered_terminal.retained_frames)
|
|
180
|
+
unknowns.push({
|
|
181
|
+
scope: "terminal",
|
|
182
|
+
reason: "Cumulative rendered state and visible-line bytes exceeded output_bytes; whole rendered frames were omitted. Raw PTY coverage is reported separately. See truncation_details.rendered_terminal.",
|
|
183
|
+
});
|
|
184
|
+
for (const [name, coverage] of [
|
|
185
|
+
["before", details.filesystem_before],
|
|
186
|
+
["after_settlement", details.filesystem_after],
|
|
187
|
+
]) {
|
|
188
|
+
if (coverage.enumeration_truncated)
|
|
189
|
+
unknowns.push({
|
|
190
|
+
scope: "filesystem",
|
|
191
|
+
reason: `Filesystem ${name} path enumeration was incomplete: ${coverage.enumeration_reasons.join(", ")}. See truncation_details.`,
|
|
192
|
+
});
|
|
193
|
+
if (coverage.hash_omissions.length > 0)
|
|
194
|
+
unknowns.push({
|
|
195
|
+
scope: "filesystem",
|
|
196
|
+
reason: `Filesystem ${name} omitted ${String(coverage.hash_omissions.length)} whole-file digests; per-path reasons and remaining file_bytes budget are in truncation_details.`,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
if (details.process.sampling_partial)
|
|
200
|
+
unknowns.push({
|
|
201
|
+
scope: "process",
|
|
202
|
+
reason: "Process sampling stopped with incomplete observations; sample_limit is reported in truncation_details.process.",
|
|
203
|
+
});
|
|
204
|
+
return unknowns;
|
|
205
|
+
};
|
|
158
206
|
const identityFromStats = (stats) => ({
|
|
159
207
|
dev: stats.dev,
|
|
160
208
|
ino: stats.ino,
|
|
@@ -301,7 +349,8 @@ export const createRunManifest = async (scenario, startedAt, completedAt, execut
|
|
|
301
349
|
normalization_sha256: digestProcessCommitment(scenario.normalization),
|
|
302
350
|
};
|
|
303
351
|
};
|
|
304
|
-
export const observeSettlement = async (runId, processGroupIds, settleMs, recordEvent = () => undefined, platform = process.platform) => {
|
|
352
|
+
export const observeSettlement = async (runId, processGroupIds, settleMs, recordEvent = () => undefined, platform = process.platform, signal) => {
|
|
353
|
+
assertNotCancelled(signal);
|
|
305
354
|
if (platform === "win32") {
|
|
306
355
|
recordEvent("lifecycle", 1);
|
|
307
356
|
return { state: "unverifiable", elapsed_ms: 0 };
|
|
@@ -310,11 +359,9 @@ export const observeSettlement = async (runId, processGroupIds, settleMs, record
|
|
|
310
359
|
let consecutiveEmpty = 0;
|
|
311
360
|
let deadlineReached = false;
|
|
312
361
|
while (!deadlineReached) {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
processGroupId,
|
|
317
|
-
})));
|
|
362
|
+
assertNotCancelled(signal);
|
|
363
|
+
const observations = await Promise.all([...new Set(processGroupIds)].map((processGroupId) => observeOwnedProcessGroup({ runId, leaderPid: processGroupId, processGroupId }, undefined, signal)));
|
|
364
|
+
assertNotCancelled(signal);
|
|
318
365
|
if (observations.some(({ state }) => state === "unverifiable")) {
|
|
319
366
|
recordEvent("lifecycle", 1);
|
|
320
367
|
return { state: "unverifiable", elapsed_ms: Date.now() - started };
|
|
@@ -331,7 +378,7 @@ export const observeSettlement = async (runId, processGroupIds, settleMs, record
|
|
|
331
378
|
deadlineReached = Date.now() - started >= settleMs;
|
|
332
379
|
if (deadlineReached)
|
|
333
380
|
break;
|
|
334
|
-
await
|
|
381
|
+
await delay(50, undefined, { signal });
|
|
335
382
|
}
|
|
336
383
|
recordEvent("lifecycle", 1);
|
|
337
384
|
return { state: "alive_at_deadline", elapsed_ms: Date.now() - started };
|
|
@@ -403,6 +450,50 @@ const verifyTokenOwnedProcessesUntilSettled = async (verify) => {
|
|
|
403
450
|
}
|
|
404
451
|
return result;
|
|
405
452
|
};
|
|
453
|
+
const releaseCapturedProcessGroup = async (ownership, host) => {
|
|
454
|
+
if (host.platform === "win32")
|
|
455
|
+
return {
|
|
456
|
+
state: "unverified",
|
|
457
|
+
reason: "owned process cleanup is unverifiable on Windows without process-job authority",
|
|
458
|
+
};
|
|
459
|
+
let outcome = {
|
|
460
|
+
state: "cleaned",
|
|
461
|
+
reason: null,
|
|
462
|
+
};
|
|
463
|
+
const unverified = [];
|
|
464
|
+
try {
|
|
465
|
+
const cleaned = await host.cleanupProcessGroup(ownership);
|
|
466
|
+
unverified.push(...(cleaned.unverified ?? []));
|
|
467
|
+
if (!cleaned.cleaned) {
|
|
468
|
+
outcome = { state: "unverified", reason: cleaned.reason };
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
471
|
+
const verified = await verifyTokenOwnedProcessesUntilSettled(() => host.verifyTokenOwnedProcesses(ownership.runId, undefined, ownership.captureBaseline, ownership));
|
|
472
|
+
unverified.push(...(verified.unverified ?? []));
|
|
473
|
+
if (!verified.cleaned)
|
|
474
|
+
outcome = { state: "unverified", reason: verified.reason };
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
catch (cause) {
|
|
478
|
+
outcome = {
|
|
479
|
+
state: "failed",
|
|
480
|
+
reason: cause instanceof Error
|
|
481
|
+
? cause.message || cause.name || "owned process cleanup failed"
|
|
482
|
+
: "owned process cleanup failed",
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
return unverified.length === 0
|
|
486
|
+
? outcome
|
|
487
|
+
: {
|
|
488
|
+
...outcome,
|
|
489
|
+
unverified_processes: [
|
|
490
|
+
...new Map(unverified.map(({ pid, diagnostic }) => [
|
|
491
|
+
`${String(pid)}:${diagnostic}`,
|
|
492
|
+
{ pid, reason: diagnostic },
|
|
493
|
+
])).values(),
|
|
494
|
+
],
|
|
495
|
+
};
|
|
496
|
+
};
|
|
406
497
|
export const releaseProcessResources = async (options) => {
|
|
407
498
|
const host = options.host ?? processCaptureCleanupHost;
|
|
408
499
|
for (const timer of options.timers)
|
|
@@ -422,60 +513,20 @@ export const releaseProcessResources = async (options) => {
|
|
|
422
513
|
: "renderer dispose failed",
|
|
423
514
|
};
|
|
424
515
|
}
|
|
425
|
-
|
|
426
|
-
state:
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
leaderPid: terminalPid,
|
|
440
|
-
processGroupId: terminalPid,
|
|
441
|
-
...(options.sampledProcessGroupIds === undefined
|
|
442
|
-
? {}
|
|
443
|
-
: { sampledProcessGroupIds: options.sampledProcessGroupIds }),
|
|
444
|
-
};
|
|
445
|
-
const cleaned = await host.cleanupProcessGroup({
|
|
446
|
-
runId: options.runId,
|
|
447
|
-
leaderPid: terminalPid,
|
|
448
|
-
processGroupId: terminalPid,
|
|
449
|
-
sweepTokenOwnedProcesses: true,
|
|
450
|
-
...(options.sampledProcessGroupIds === undefined
|
|
451
|
-
? {}
|
|
452
|
-
: { sampledProcessGroupIds: options.sampledProcessGroupIds }),
|
|
453
|
-
...(options.captureBaseline === undefined
|
|
454
|
-
? {}
|
|
455
|
-
: { captureBaseline: options.captureBaseline }),
|
|
456
|
-
});
|
|
457
|
-
const unverified = [...(cleaned.unverified ?? [])];
|
|
458
|
-
if (!cleaned.cleaned) {
|
|
459
|
-
ownedProcessGroup = { state: "unverified", reason: cleaned.reason };
|
|
460
|
-
}
|
|
461
|
-
else {
|
|
462
|
-
const verified = await verifyTokenOwnedProcessesUntilSettled(() => host.verifyTokenOwnedProcesses(options.runId, undefined, options.captureBaseline, relation));
|
|
463
|
-
unverified.push(...(verified.unverified ?? []));
|
|
464
|
-
if (!verified.cleaned)
|
|
465
|
-
ownedProcessGroup = { state: "unverified", reason: verified.reason };
|
|
466
|
-
}
|
|
467
|
-
if (unverified.length > 0)
|
|
468
|
-
ownedProcessGroup = {
|
|
469
|
-
...ownedProcessGroup,
|
|
470
|
-
unverified_processes: [
|
|
471
|
-
...new Map(unverified.map(({ pid, diagnostic }) => [
|
|
472
|
-
`${String(pid)}:${diagnostic}`,
|
|
473
|
-
{ pid, reason: diagnostic },
|
|
474
|
-
])).values(),
|
|
475
|
-
],
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
}
|
|
516
|
+
const ownedProcessGroup = options.terminal === undefined
|
|
517
|
+
? { state: "not_required", reason: null }
|
|
518
|
+
: await releaseCapturedProcessGroup({
|
|
519
|
+
runId: options.runId,
|
|
520
|
+
leaderPid: options.terminal.pid,
|
|
521
|
+
processGroupId: options.terminal.pid,
|
|
522
|
+
sweepTokenOwnedProcesses: true,
|
|
523
|
+
...(options.sampledProcessGroupIds === undefined
|
|
524
|
+
? {}
|
|
525
|
+
: { sampledProcessGroupIds: options.sampledProcessGroupIds }),
|
|
526
|
+
...(options.captureBaseline === undefined
|
|
527
|
+
? {}
|
|
528
|
+
: { captureBaseline: options.captureBaseline }),
|
|
529
|
+
}, host);
|
|
479
530
|
let temporaryRoot = {
|
|
480
531
|
state: "cleaned",
|
|
481
532
|
reason: null,
|
|
@@ -507,12 +558,14 @@ export const cleanupReportFailure = (report) => {
|
|
|
507
558
|
};
|
|
508
559
|
export const captureTerminalFrames = (options) => {
|
|
509
560
|
let outputBytes = 0;
|
|
510
|
-
let
|
|
561
|
+
let observedBytes = 0;
|
|
562
|
+
let observedFrames = 0;
|
|
511
563
|
options.terminal.onData((data) => {
|
|
512
564
|
options.onOutput();
|
|
513
565
|
const bytes = Buffer.byteLength(data);
|
|
566
|
+
observedBytes += bytes;
|
|
567
|
+
observedFrames += 1;
|
|
514
568
|
if (outputBytes + bytes > options.scenario.limits.output_bytes) {
|
|
515
|
-
truncated = true;
|
|
516
569
|
return;
|
|
517
570
|
}
|
|
518
571
|
outputBytes += bytes;
|
|
@@ -523,11 +576,18 @@ export const captureTerminalFrames = (options) => {
|
|
|
523
576
|
sequence,
|
|
524
577
|
at_ms: atMs,
|
|
525
578
|
data: normalized,
|
|
579
|
+
...(normalized === data ? {} : { raw_data: data }),
|
|
526
580
|
});
|
|
527
581
|
options.renderer.write(data, atMs);
|
|
528
582
|
options.recordEvent("frames", sequence);
|
|
529
583
|
});
|
|
530
|
-
return () =>
|
|
584
|
+
return () => ({
|
|
585
|
+
budget_bytes: options.scenario.limits.output_bytes,
|
|
586
|
+
observed_bytes: observedBytes,
|
|
587
|
+
retained_bytes: outputBytes,
|
|
588
|
+
observed_frames: observedFrames,
|
|
589
|
+
retained_frames: options.frames.length,
|
|
590
|
+
});
|
|
531
591
|
};
|
|
532
592
|
export const resolveProcessResult = (capture, executionFailure, cleanup, observations, partialContext) => {
|
|
533
593
|
const cleanupFailure = cleanupReportFailure(cleanup);
|
|
@@ -660,16 +720,30 @@ export const prepareProcessCapture = async (scenario, signal, captureSnapshot =
|
|
|
660
720
|
await host.prepareOwnershipInspector?.(signal);
|
|
661
721
|
assertNotCancelled(signal);
|
|
662
722
|
const before = await captureSnapshot(scenario, signal);
|
|
723
|
+
const runId = randomUUID();
|
|
663
724
|
const temporaryRoot = await host.createTemporaryRoot();
|
|
664
725
|
try {
|
|
665
726
|
assertNotCancelled(signal);
|
|
666
|
-
const runId = randomUUID();
|
|
667
727
|
const ownershipBaseline = (await host.captureOwnershipBaseline?.(signal)) ?? [];
|
|
668
728
|
assertNotCancelled(signal);
|
|
669
729
|
return { temporaryRoot, runId, ownershipBaseline, before };
|
|
670
730
|
}
|
|
671
731
|
catch (cause) {
|
|
672
|
-
await
|
|
732
|
+
const cleanup = await releaseProcessResources({
|
|
733
|
+
timers: new Set(),
|
|
734
|
+
terminal: undefined,
|
|
735
|
+
renderer: undefined,
|
|
736
|
+
runId,
|
|
737
|
+
temporaryRoot,
|
|
738
|
+
host: { ...processCaptureCleanupHost, removeTemporaryRoot: host.cleanup },
|
|
739
|
+
});
|
|
740
|
+
resolveProcessResult(undefined, normalizeCaptureFailure(cause, signal), cleanup, createProcessCaptureObservationBuffer({
|
|
741
|
+
frames: [],
|
|
742
|
+
interactions: [],
|
|
743
|
+
samples: [],
|
|
744
|
+
eventJournal: [],
|
|
745
|
+
before,
|
|
746
|
+
}), { scenario });
|
|
673
747
|
throw cause;
|
|
674
748
|
}
|
|
675
749
|
};
|
|
@@ -1,12 +1,42 @@
|
|
|
1
|
-
|
|
1
|
+
import { sep } from "node:path";
|
|
2
|
+
const unobservedAbsenceReason = (path, phase, completeRoots, filesByPath) => {
|
|
3
|
+
const alias = path.slice(0, path.indexOf(":"));
|
|
4
|
+
if (!completeRoots.has(alias))
|
|
5
|
+
return `The ${phase} snapshot did not exhaust path enumeration under ${alias}; absence remains unknown.`;
|
|
6
|
+
const rootPath = `${alias}:.`;
|
|
7
|
+
if (path !== rootPath && filesByPath.get(rootPath)?.type === "symlink")
|
|
8
|
+
return `The ${phase} snapshot did not follow the symbolic link at ${rootPath}; descendant absence remains unknown.`;
|
|
9
|
+
for (let index = path.lastIndexOf(sep); index > 0; index = path.lastIndexOf(sep, index - 1)) {
|
|
10
|
+
const parent = path.slice(0, index);
|
|
11
|
+
if (filesByPath.get(parent)?.type === "symlink")
|
|
12
|
+
return `The ${phase} snapshot did not follow the symbolic link at ${parent}; descendant absence remains unknown.`;
|
|
13
|
+
}
|
|
14
|
+
return undefined;
|
|
15
|
+
};
|
|
16
|
+
/** Classify effects only from observed path absence, metadata, and content hashes. */
|
|
2
17
|
export const classifyFilesystemEffects = (before, after) => {
|
|
3
|
-
const beforeByPath = new Map(before.map((file) => [file.path, file]));
|
|
4
|
-
const afterByPath = new Map(after.map((file) => [file.path, file]));
|
|
18
|
+
const beforeByPath = new Map(before.files.map((file) => [file.path, file]));
|
|
19
|
+
const afterByPath = new Map(after.files.map((file) => [file.path, file]));
|
|
20
|
+
const beforeCompleteRoots = new Set(before.completeRoots);
|
|
21
|
+
const afterCompleteRoots = new Set(after.completeRoots);
|
|
5
22
|
return [...new Set([...beforeByPath.keys(), ...afterByPath.keys()])]
|
|
6
23
|
.sort()
|
|
7
24
|
.map((path) => {
|
|
8
25
|
const beforeFile = beforeByPath.get(path) ?? null;
|
|
9
26
|
const afterFile = afterByPath.get(path) ?? null;
|
|
27
|
+
const reason = beforeFile === null
|
|
28
|
+
? unobservedAbsenceReason(path, "before", beforeCompleteRoots, beforeByPath)
|
|
29
|
+
: afterFile === null
|
|
30
|
+
? unobservedAbsenceReason(path, "after", afterCompleteRoots, afterByPath)
|
|
31
|
+
: undefined;
|
|
32
|
+
if (reason !== undefined)
|
|
33
|
+
return {
|
|
34
|
+
path,
|
|
35
|
+
status: "unknown",
|
|
36
|
+
before: beforeFile,
|
|
37
|
+
after: afterFile,
|
|
38
|
+
reason,
|
|
39
|
+
};
|
|
10
40
|
if (beforeFile === null) {
|
|
11
41
|
if (afterFile === null)
|
|
12
42
|
throw new TypeError(`Filesystem effect ${path} has no file state`);
|
|
@@ -24,11 +54,26 @@ export const classifyFilesystemEffects = (before, after) => {
|
|
|
24
54
|
before: beforeFile,
|
|
25
55
|
after: null,
|
|
26
56
|
};
|
|
57
|
+
const metadataChanged = beforeFile.type !== afterFile.type ||
|
|
58
|
+
beforeFile.mode !== afterFile.mode ||
|
|
59
|
+
beforeFile.size !== afterFile.size ||
|
|
60
|
+
beforeFile.symlink_target !== afterFile.symlink_target;
|
|
61
|
+
if (!metadataChanged &&
|
|
62
|
+
beforeFile.type === "file" &&
|
|
63
|
+
afterFile.type === "file" &&
|
|
64
|
+
(beforeFile.sha256 === null || afterFile.sha256 === null))
|
|
65
|
+
return {
|
|
66
|
+
path,
|
|
67
|
+
status: "unknown",
|
|
68
|
+
before: beforeFile,
|
|
69
|
+
after: afterFile,
|
|
70
|
+
reason: "A file content hash is unavailable in at least one snapshot; matching metadata does not establish unchanged contents.",
|
|
71
|
+
};
|
|
27
72
|
return {
|
|
28
73
|
path,
|
|
29
|
-
status:
|
|
30
|
-
? "
|
|
31
|
-
: "
|
|
74
|
+
status: metadataChanged || beforeFile.sha256 !== afterFile.sha256
|
|
75
|
+
? "modified"
|
|
76
|
+
: "unchanged",
|
|
32
77
|
before: beforeFile,
|
|
33
78
|
after: afterFile,
|
|
34
79
|
};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { parseProcessCapture } from "../../domain/process/
|
|
1
|
+
import { parseProcessCapture } from "../../domain/process/processCaptureParsing.js";
|
|
2
2
|
import { err, ok } from "../../domain/result.js";
|
|
3
3
|
import { AnalysisCapabilityUnavailableError } from "../../domain/analysisErrorCore.js";
|
|
4
4
|
import {} from "../../domain/analysisErrorBase.js";
|
|
5
|
-
import { describeProcessCaptureExecutionFailure, ProcessCaptureError, processCaptureCancelled, } from "./ProcessCaptureError.js";
|
|
6
|
-
export { ProcessCaptureError } from "./ProcessCaptureError.js";
|
|
5
|
+
import { describeProcessCaptureExecutionFailure, ProcessCaptureError, normalizeCaptureFailure, processCaptureCancelled, } from "./ProcessCaptureError.js";
|
|
7
6
|
import { startProcessSampler } from "./ProcessSampling.js";
|
|
8
7
|
import { snapshotRoots } from "./FilesystemSnapshot.js";
|
|
9
8
|
import { TerminalRenderer } from "./TerminalRenderer.js";
|
|
@@ -15,14 +14,11 @@ import { createProcessCaptureJournal, scheduleScenarioInteractions, } from "./Pr
|
|
|
15
14
|
import { makeProcessCaptureEnvironment } from "./ProcessCaptureEnvironment.js";
|
|
16
15
|
import { classifyFilesystemEffects } from "./ProcessFilesystemEffects.js";
|
|
17
16
|
import { processCaptureOwnershipUnavailableReason } from "./ProcessCaptureCapability.js";
|
|
18
|
-
import { DarwinProcessOwnershipInspectionError } from "../DarwinProcessRunTokenReader.js";
|
|
19
|
-
export { probeProcessCaptureCapability } from "./ProcessCaptureCapability.js";
|
|
20
17
|
const cleanupFailedStartup = async (options) => {
|
|
21
18
|
const sampledProcessGroupIds = options.terminal !== undefined &&
|
|
22
19
|
options.observations?.process_samples.state === "available"
|
|
23
20
|
? selectCapturedProcessGroupIds(options.terminal.pid, options.observations.process_samples.value).filter((groupId) => groupId !== options.terminal?.pid)
|
|
24
21
|
: undefined;
|
|
25
|
-
options.terminal?.kill("SIGKILL");
|
|
26
22
|
if (options.observations !== undefined && options.renderer !== undefined) {
|
|
27
23
|
try {
|
|
28
24
|
options.observations.rendered_frames = {
|
|
@@ -89,7 +85,7 @@ const startCaptureRuntime = async (options) => {
|
|
|
89
85
|
value: scenario.normalization.pids ? 1 : terminal.pid,
|
|
90
86
|
};
|
|
91
87
|
const executableIdentity = observeLaunchedExecutable(scenario.executable, selectedExecutable);
|
|
92
|
-
const
|
|
88
|
+
const rawTerminalRetention = captureTerminalFrames({
|
|
93
89
|
...options,
|
|
94
90
|
terminal,
|
|
95
91
|
started,
|
|
@@ -117,7 +113,7 @@ const startCaptureRuntime = async (options) => {
|
|
|
117
113
|
startedAt,
|
|
118
114
|
executableIdentity,
|
|
119
115
|
lastOutput: () => lastOutput,
|
|
120
|
-
|
|
116
|
+
rawTerminalRetention,
|
|
121
117
|
stopSampler,
|
|
122
118
|
};
|
|
123
119
|
}
|
|
@@ -181,18 +177,6 @@ const finishProcessRun = async (options) => {
|
|
|
181
177
|
: { scenario: options.scenario, rootPid };
|
|
182
178
|
return resolveProcessResult(cleanupFailure === undefined ? verifiedCapture : capture, executionFailure, cleanup, options.observations, partialContext);
|
|
183
179
|
};
|
|
184
|
-
/** Preserve typed process-inspection preflight failures at the capture boundary. */
|
|
185
|
-
export const normalizeCaptureFailure = (cause, signal) => {
|
|
186
|
-
if (cause instanceof ProcessCaptureError)
|
|
187
|
-
return cause;
|
|
188
|
-
if (cause instanceof DarwinProcessOwnershipInspectionError)
|
|
189
|
-
return new ProcessCaptureError(cause.message, { cause });
|
|
190
|
-
if (signal?.aborted === true &&
|
|
191
|
-
(cause === signal.reason ||
|
|
192
|
-
(cause instanceof Error && cause.name === "AbortError")))
|
|
193
|
-
return processCaptureCancelled();
|
|
194
|
-
return cause;
|
|
195
|
-
};
|
|
196
180
|
const completeCapture = async (options) => {
|
|
197
181
|
const unavailableReason = (stage, cause) => `${stage} failed: ${cause instanceof Error ? cause.message : "unknown failure"}`;
|
|
198
182
|
const { runtime, scenario } = options;
|
|
@@ -201,7 +185,7 @@ const completeCapture = async (options) => {
|
|
|
201
185
|
throw processCaptureCancelled();
|
|
202
186
|
let settlement;
|
|
203
187
|
try {
|
|
204
|
-
settlement = await observeSettlement(options.runId, selectCapturedProcessGroupIds(runtime.terminal.pid, options.samples), scenario.settle_ms, options.recordEvent, options.hostPlatform);
|
|
188
|
+
settlement = await observeSettlement(options.runId, selectCapturedProcessGroupIds(runtime.terminal.pid, options.samples), scenario.settle_ms, options.recordEvent, options.hostPlatform, options.signal);
|
|
205
189
|
}
|
|
206
190
|
catch (cause) {
|
|
207
191
|
options.observationBuffer.settlement = {
|
|
@@ -214,7 +198,8 @@ const completeCapture = async (options) => {
|
|
|
214
198
|
state: "available",
|
|
215
199
|
value: settlement,
|
|
216
200
|
};
|
|
217
|
-
const
|
|
201
|
+
const sampling = await runtime.stopSampler();
|
|
202
|
+
const samplingPartial = sampling.partial;
|
|
218
203
|
await settleProcessCaptureJournal(options.eventJournal);
|
|
219
204
|
assertNotCancelled(options.signal);
|
|
220
205
|
let after;
|
|
@@ -235,7 +220,7 @@ const completeCapture = async (options) => {
|
|
|
235
220
|
...options.observationBuffer.filesystem_snapshots,
|
|
236
221
|
after: {
|
|
237
222
|
state: "available",
|
|
238
|
-
value:
|
|
223
|
+
value: after,
|
|
239
224
|
},
|
|
240
225
|
};
|
|
241
226
|
options.recordEvent("filesystem_checkpoints", 1);
|
|
@@ -266,7 +251,7 @@ const completeCapture = async (options) => {
|
|
|
266
251
|
name: "after_settlement",
|
|
267
252
|
at_ms: Math.max(0, Date.now() - runtime.started),
|
|
268
253
|
files: after.files,
|
|
269
|
-
effects: classifyFilesystemEffects(options.before
|
|
254
|
+
effects: classifyFilesystemEffects(options.before, after),
|
|
270
255
|
truncated: after.truncated,
|
|
271
256
|
},
|
|
272
257
|
];
|
|
@@ -282,19 +267,19 @@ const completeCapture = async (options) => {
|
|
|
282
267
|
throw cause;
|
|
283
268
|
}
|
|
284
269
|
options.observationBuffer.manifest = { state: "available", value: manifest };
|
|
285
|
-
const truncated = options.initiallyTruncated ||
|
|
286
|
-
after.truncated ||
|
|
287
|
-
runtime.framesTruncated() ||
|
|
288
|
-
checkpoints.some(({ truncated: partial }) => partial) ||
|
|
289
|
-
samplingPartial ||
|
|
290
|
-
runtime.renderer.truncated();
|
|
291
270
|
return buildCaptureResult({
|
|
292
271
|
frames: options.frames,
|
|
293
272
|
exit: { ...options.exit, reason },
|
|
294
273
|
samples: options.samples,
|
|
295
274
|
before: options.before,
|
|
296
275
|
after,
|
|
297
|
-
|
|
276
|
+
truncationDetails: {
|
|
277
|
+
raw_terminal: runtime.rawTerminalRetention(),
|
|
278
|
+
rendered_terminal: runtime.renderer.retention(),
|
|
279
|
+
filesystem_before: options.before.coverage,
|
|
280
|
+
filesystem_after: after.coverage,
|
|
281
|
+
process: sampling.coverage,
|
|
282
|
+
},
|
|
298
283
|
scenario,
|
|
299
284
|
rootPid: runtime.terminal.pid,
|
|
300
285
|
samplingPartial,
|
|
@@ -380,7 +365,6 @@ const runProcessScenario = async (scenario, signal, hostEnvironment = process.en
|
|
|
380
365
|
samples,
|
|
381
366
|
interactions,
|
|
382
367
|
exit,
|
|
383
|
-
initiallyTruncated: before.truncated,
|
|
384
368
|
eventJournal,
|
|
385
369
|
observationBuffer: observations,
|
|
386
370
|
recordEvent,
|
|
@@ -389,7 +373,6 @@ const runProcessScenario = async (scenario, signal, hostEnvironment = process.en
|
|
|
389
373
|
});
|
|
390
374
|
}
|
|
391
375
|
catch (cause) {
|
|
392
|
-
runtime?.terminal.kill("SIGKILL");
|
|
393
376
|
executionFailure = normalizeCaptureFailure(cause, signal);
|
|
394
377
|
if (runtime !== undefined &&
|
|
395
378
|
observations.rendered_frames.state === "unavailable" &&
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isIP } from "node:net";
|
|
1
2
|
/** Bucket one elapsed process-capture timestamp under scenario normalization. */
|
|
2
3
|
export const normalizeProcessElapsedTime = (elapsedMs, timeBucketMs) => Math.floor(elapsedMs / timeBucketMs) * timeBucketMs;
|
|
3
4
|
/** Normalize one terminal/protocol payload under explicitly selected scenario rules. */
|
|
@@ -10,14 +11,31 @@ export const normalizeProcessText = (value, scenario, temporaryRoot, pid) => {
|
|
|
10
11
|
for (const [index, root] of scenario.filesystem_observation_paths.entries())
|
|
11
12
|
normalized = normalized.replaceAll(root, `<filesystem-root-${String(index)}>`);
|
|
12
13
|
}
|
|
14
|
+
if (scenario.normalization.ports)
|
|
15
|
+
normalized = normalizePortTokens(normalized);
|
|
13
16
|
if (scenario.normalization.pids)
|
|
14
17
|
normalized = normalizePidTokens(normalized, [pid]);
|
|
15
|
-
if (scenario.normalization.ports)
|
|
16
|
-
normalized = normalized.replaceAll(/(?<=[:=])\d{2,5}\b/g, "<port>");
|
|
17
18
|
for (const pattern of scenario.normalization.patterns)
|
|
18
19
|
normalized = normalized.replaceAll(pattern.pattern, pattern.replacement);
|
|
19
20
|
return normalized;
|
|
20
21
|
};
|
|
22
|
+
// A port may end a sentence, but a period followed by a letter, digit, or
|
|
23
|
+
// underscore in any script continues a decimal, version, or host name and is
|
|
24
|
+
// not a port boundary.
|
|
25
|
+
// PTY chunks are normalized independently, so a period that ends the chunk
|
|
26
|
+
// stays unnormalized: its continuation may arrive in the next chunk.
|
|
27
|
+
const normalizePortTokens = (value) => {
|
|
28
|
+
const endpointNormalized = value.replaceAll(/(\b[a-z][a-z0-9+.-]*:\/\/[^\s/?#"'<>]+|\blocalhost|\b(?:\d{1,3}\.){3}\d{1,3}|\[[\da-f:.%]+\]):(\d{1,5})(?![\p{L}\p{N}_@:]|\.(?:[\p{L}\p{N}_]|$))/giu, (match, endpoint, port) => {
|
|
29
|
+
if (Number(port) > 65_535)
|
|
30
|
+
return match;
|
|
31
|
+
const isEndpoint = endpoint.includes("://")
|
|
32
|
+
? URL.canParse(`${endpoint}:${port}`)
|
|
33
|
+
: endpoint.toLowerCase() === "localhost" ||
|
|
34
|
+
isIP(endpoint.replace(/^\[|\]$/gu, "")) !== 0;
|
|
35
|
+
return isEndpoint ? `${endpoint}:<port>` : match;
|
|
36
|
+
});
|
|
37
|
+
return endpointNormalized.replaceAll(/(\b(?:port|tcp_port|udp_port|listen)\b["']?\s*[:=]\s*)(\d{1,5})(?![\p{L}\p{N}_]|\.(?:[\p{L}\p{N}_]|$))/giu, (match, prefix, port) => Number(port) <= 65_535 ? `${prefix}<port>` : match);
|
|
38
|
+
};
|
|
21
39
|
/** Project sampled observations under the caller-selected normalization rules. */
|
|
22
40
|
export const normalizeProcessSamples = (samples, scenario, rootPid) => {
|
|
23
41
|
const identifiers = [
|
|
@@ -328,6 +328,9 @@ export const startProcessSampler = (options) => {
|
|
|
328
328
|
let stopped = false;
|
|
329
329
|
let abortCurrent;
|
|
330
330
|
let partial = false;
|
|
331
|
+
let limitReached = false;
|
|
332
|
+
let samplingFailures = 0;
|
|
333
|
+
let firstSamplingFailure = null;
|
|
331
334
|
let rootInitialized = false;
|
|
332
335
|
const sample = () => {
|
|
333
336
|
if (stopped || pending !== undefined)
|
|
@@ -363,6 +366,7 @@ export const startProcessSampler = (options) => {
|
|
|
363
366
|
continue;
|
|
364
367
|
if (samples.length >= limit) {
|
|
365
368
|
partial = true;
|
|
369
|
+
limitReached = true;
|
|
366
370
|
continue;
|
|
367
371
|
}
|
|
368
372
|
lastObservations.set(value.pid, observation);
|
|
@@ -372,8 +376,16 @@ export const startProcessSampler = (options) => {
|
|
|
372
376
|
}
|
|
373
377
|
})
|
|
374
378
|
.catch((cause) => {
|
|
375
|
-
if (!(cause instanceof Error && cause.name === "AbortError"))
|
|
379
|
+
if (!(cause instanceof Error && cause.name === "AbortError")) {
|
|
376
380
|
partial = true;
|
|
381
|
+
samplingFailures += 1;
|
|
382
|
+
firstSamplingFailure ??=
|
|
383
|
+
cause instanceof Error
|
|
384
|
+
? `${cause.name}: ${cause.message}`
|
|
385
|
+
: typeof cause === "string"
|
|
386
|
+
? cause
|
|
387
|
+
: `Unexpected sampling rejection (${typeof cause})`;
|
|
388
|
+
}
|
|
377
389
|
})
|
|
378
390
|
.then(() => {
|
|
379
391
|
abortCurrent = undefined;
|
|
@@ -387,6 +399,17 @@ export const startProcessSampler = (options) => {
|
|
|
387
399
|
clearInterval(timer);
|
|
388
400
|
abortCurrent?.();
|
|
389
401
|
await pending;
|
|
390
|
-
return {
|
|
402
|
+
return {
|
|
403
|
+
partial,
|
|
404
|
+
coverage: {
|
|
405
|
+
sample_limit: limit,
|
|
406
|
+
sampling_partial: partial,
|
|
407
|
+
retained_samples: samples.length,
|
|
408
|
+
sample_limit_reached: limitReached,
|
|
409
|
+
sampling_failures: samplingFailures,
|
|
410
|
+
first_sampling_failure: firstSamplingFailure,
|
|
411
|
+
coverage: "sampled",
|
|
412
|
+
},
|
|
413
|
+
};
|
|
391
414
|
};
|
|
392
415
|
};
|