rea-agents 3.2.0 → 4.0.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 +183 -332
- package/bridge/ghidra/ReaGhidraBridge.java +561 -74
- package/bridge/hopper_bridge.py +70 -27
- package/bridge/native/ReaNativeUI.swift +157 -0
- package/dist/application/AnalysisContextQueries.js +19 -5
- package/dist/application/AnalysisSnapshotCache.js +30 -11
- package/dist/application/AppleAssetCatalogAnalysis.js +171 -0
- package/dist/application/ArtifactExtractionDestination.js +0 -12
- package/dist/application/ArtifactGraphConstruction.js +44 -11
- package/dist/application/ArtifactInventory/classify.js +7 -15
- package/dist/application/ArtifactInventory/hash.js +4 -2
- package/dist/application/ArtifactInventory/policy.js +2 -17
- package/dist/application/ArtifactInventory/reader.js +3 -3
- package/dist/application/ArtifactInventory/scanCanonical.js +2 -2
- package/dist/application/ArtifactInventory/scanReader.js +12 -4
- package/dist/application/ArtifactInventory/types.js +0 -3
- package/dist/application/BinarySession.js +28 -43
- package/dist/application/BinarySessionExecution.js +37 -1
- package/dist/application/BinaryTargetResolver.js +50 -4
- package/dist/application/BrowserEvidence.js +36 -7
- package/dist/application/BrowserObservationService.js +17 -44
- package/dist/application/BrowserScenarioCaptureService.js +2 -35
- package/dist/application/BrowserScenarioEvidence.js +13 -9
- package/dist/application/CapabilityClientRequirements.js +2 -11
- package/dist/application/CapabilityInventory.js +21 -35
- package/dist/application/ClientConfigurationDocument.js +84 -7
- package/dist/application/ClientRegistrationIdentity.js +32 -0
- package/dist/application/ClientRegistrationStatus.js +59 -6
- package/dist/application/DirectAnalysis.js +37 -58
- package/dist/application/DirectAnalysisStatus.js +4 -4
- package/dist/application/Doctor.js +89 -80
- package/dist/application/DoctorDiagnostics.js +2 -26
- package/dist/application/DoctorScope.js +8 -14
- package/dist/application/ElectronActiveEvidence.js +10 -27
- package/dist/application/ElectronActiveObservationService.js +9 -36
- package/dist/application/ElectronBoundaryAnalysis.js +2 -0
- package/dist/application/ElectronBoundaryGraphNative.js +1 -1
- package/dist/application/ElectronEvidence.js +8 -3
- package/dist/application/ElectronObservationService.js +9 -25
- package/dist/application/EnhancedLiteralTracing.js +4 -8
- package/dist/application/EnhancedTools.js +15 -35
- package/dist/application/FilesystemSnapshot.js +7 -8
- package/dist/application/JavaScriptApplicationEvidenceGraph.js +2 -1
- package/dist/application/JavaScriptApplicationWorkflowService.js +31 -7
- package/dist/application/JavaScriptArtifactAnalysis.js +6 -4
- package/dist/application/JavaScriptArtifactFiles.js +5 -0
- package/dist/application/JavaScriptArtifactPathResolution.js +179 -47
- package/dist/application/JavaScriptRuntimeObservationEvidence.js +6 -3
- package/dist/application/JavaScriptRuntimeObservationService.js +9 -25
- package/dist/application/JavaScriptRuntimeReconciliationService.js +45 -4
- package/dist/application/JavaScriptSemanticGraphAsyncProjection.js +11 -0
- package/dist/application/JavaScriptSemanticGraphChildProcessProjection.js +11 -0
- package/dist/application/JavaScriptSemanticGraphDataProjection.js +11 -0
- package/dist/application/JavaScriptSemanticGraphFlowProjection.js +14 -5
- package/dist/application/JsonFiles.js +1 -1
- package/dist/application/LazyAnalysisProvider.js +27 -6
- package/dist/application/ManagedMemberComparisonService.js +19 -6
- package/dist/application/NativeApiInspection.js +2 -0
- package/dist/application/NativeCallRoutes.js +72 -0
- package/dist/application/NativeDispatchMetadataInspection.js +33 -0
- package/dist/application/NativeUiActionTrace.js +73 -49
- package/dist/application/NativeValueTrace.js +320 -0
- package/dist/application/ProcessCaptureCapability.js +32 -5
- package/dist/application/ProcessCaptureEnvironment.js +9 -26
- package/dist/application/ProcessCaptureError.js +1 -5
- package/dist/application/ProcessCaptureJournal.js +3 -40
- package/dist/application/ProcessCaptureLifecycle.js +102 -111
- package/dist/application/ProcessCli.js +18 -25
- package/dist/application/ProcessEvidence.js +5 -7
- package/dist/application/ProcessFilesystemEffects.js +36 -0
- package/dist/application/ProcessHarness.js +41 -120
- package/dist/application/ProcessNormalization.js +2 -17
- package/dist/application/ProcessScenarioRuntimeValidation.js +76 -0
- package/dist/application/ReferenceSourceImport.js +3 -4
- package/dist/application/Setup.js +236 -84
- package/dist/application/SetupClientConfiguration.js +14 -9
- package/dist/application/SetupPlan.js +138 -86
- package/dist/application/SetupSkill.js +0 -1
- package/dist/application/SupportedClients.js +102 -21
- package/dist/application/Uninstall.js +31 -20
- package/dist/application/Update.js +93 -0
- package/dist/application/UpdateMaintenance.js +108 -0
- package/dist/application/UpdateRuntime.js +126 -0
- package/dist/application/runtime.js +13 -2
- package/dist/artifacts/ArtifactPaths.js +6 -8
- package/dist/artifacts/ArtifactProvider.js +94 -41
- package/dist/artifacts/AsarArtifactReader.js +19 -4
- package/dist/artifacts/KeyedArchiveReader.js +110 -0
- package/dist/artifacts/MachOSliceArtifactReader.js +53 -5
- package/dist/artifacts/ZipArtifactReader.js +18 -1
- package/dist/browser/BrowserScenarioSecrets.js +28 -1
- package/dist/browser/CdpBrowserProvider.js +36 -15
- package/dist/browser/CdpCaptureDocuments.js +22 -8
- package/dist/browser/CdpCaptureEventHandlers.js +14 -5
- package/dist/browser/CdpCaptureEventHelpers.js +13 -0
- package/dist/browser/CdpCaptureEvents.js +10 -1
- package/dist/browser/CdpElectronInspection.js +5 -10
- package/dist/browser/CdpElectronProvider.js +1 -5
- package/dist/browser/CdpElectronScripts.js +1 -1
- package/dist/browser/CdpEndpoint.js +3 -2
- package/dist/browser/CdpObservationSession.js +14 -10
- package/dist/browser/CdpPageCapture.js +1 -1
- package/dist/browser/CdpPageCaptureScripts.js +1 -1
- package/dist/browser/CdpSafeMetadata.js +5 -4
- package/dist/browser/CdpScreenshot.js +16 -5
- package/dist/browser/CdpTargetSession.js +25 -4
- package/dist/browser/CdpWebMcpDiscovery.js +93 -20
- package/dist/browser/JavaScriptRuntimeScope.js +28 -2
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +9 -8
- package/dist/browser/PlaywrightElectronActiveActions.js +3 -10
- package/dist/browser/PlaywrightElectronActiveProvider.js +5 -5
- package/dist/browser/PlaywrightScenarioActions.js +1 -1
- package/dist/browser/PlaywrightScenarioArtifacts.js +13 -25
- package/dist/browser/PlaywrightScenarioBrowser.js +28 -25
- package/dist/browser/PlaywrightScenarioEvents.js +82 -93
- package/dist/browser/PlaywrightScenarioSession.js +27 -123
- package/dist/browser/PngVisualDiff.js +22 -3
- package/dist/browser/V8InspectorCaptureProjection.js +7 -1
- package/dist/browser/V8InspectorProvider.js +60 -7
- package/dist/browser/WebSourceMapFetcher.js +99 -53
- package/dist/cli/artifactCommands.js +56 -12
- package/dist/cli/coreAnalysisCommands.js +110 -0
- package/dist/cli/managedCommands.js +1 -31
- package/dist/cli/setupCommands.js +16 -14
- package/dist/cli/utilityCommands.js +61 -4
- package/dist/cli.js +5 -7
- package/dist/cliApplicationCommands.js +0 -83
- package/dist/cliBrowserAdvancedCommands.js +7 -11
- package/dist/cliBrowserCommands.js +15 -23
- package/dist/cliBrowserContext.js +3 -24
- package/dist/cliBrowserScenarioCommands.js +2 -10
- package/dist/cliCommandNames.js +82 -7
- package/dist/cliElectronCommands.js +10 -36
- package/dist/cliJavaScriptRuntimeCommands.js +6 -30
- package/dist/cliJsonInput.js +4 -2
- package/dist/cliLogging.js +16 -7
- package/dist/cliObservationOptions.js +1 -1
- package/dist/cliOutput.js +2 -4
- package/dist/cliProcessCommands.js +6 -33
- package/dist/cliSetup.js +90 -160
- package/dist/config/environment.js +2 -78
- package/dist/config/parseConfig.js +18 -109
- package/dist/config/parsers.js +0 -23
- package/dist/contracts/applicationToolContracts.js +1 -118
- package/dist/contracts/artifactToolContracts.js +11 -19
- package/dist/contracts/browserScenarioToolContracts.js +1 -5
- package/dist/contracts/browserToolContracts.js +9 -16
- package/dist/contracts/electronToolContracts.js +5 -6
- package/dist/contracts/enhancedInputs.js +3 -2
- package/dist/contracts/errorSchemas.js +16 -40
- package/dist/contracts/functionWorkflowToolContracts.js +2 -2
- package/dist/contracts/javascriptApplicationWorkflowExamples.js +2 -2
- package/dist/contracts/javascriptRuntimeObservationToolContracts.js +4 -4
- package/dist/contracts/javascriptRuntimeReconciliationExample.js +1 -1
- package/dist/contracts/managedToolContracts.js +7 -4
- package/dist/contracts/managedWorkflowExamples.js +0 -22
- package/dist/contracts/managedWorkflowToolContracts.js +16 -31
- package/dist/contracts/nativeToolContracts.js +9 -0
- package/dist/contracts/promptContracts.js +6 -6
- package/dist/contracts/sessionToolSchemas.js +3 -3
- package/dist/contracts/toolContractExamples.js +4 -3
- package/dist/contracts/toolContracts.js +18 -7
- package/dist/contracts/toolEffects.js +34 -21
- package/dist/contracts/toolOutputSchemaGroups.js +18 -5
- package/dist/contracts/toolOutputSchemaPrimitives.js +9 -6
- package/dist/contracts/toolSchemaMetadata.js +5 -8
- package/dist/doctorRuntime.js +0 -41
- package/dist/domain/analysisErrorPresentation.js +4 -28
- package/dist/domain/analysisErrorProjection.js +33 -50
- package/dist/domain/analysisProfile.js +1 -1
- package/dist/domain/analysisSnapshot.js +77 -3
- package/dist/domain/androidApplication.js +5 -4
- package/dist/domain/appleApplication.js +5 -4
- package/dist/domain/appleAssetCatalog.js +127 -0
- package/dist/domain/artifactComparison.js +7 -11
- package/dist/domain/artifactGraph.js +8 -6
- package/dist/domain/artifactInspection.js +13 -12
- package/dist/domain/binaryTarget.js +23 -9
- package/dist/domain/browserObservation.js +43 -24
- package/dist/domain/browserObservationSchemas.js +2 -1
- package/dist/domain/browserScenario.js +7 -107
- package/dist/domain/browserScenarioCapture.js +0 -1
- package/dist/domain/browserScenarioCaptureValues.js +5 -4
- package/dist/domain/browserScenarioDiff.js +1 -3
- package/dist/domain/browserScenarioValues.js +16 -107
- package/dist/domain/bundleComparison.js +18 -17
- package/dist/domain/callPathSchemas.js +17 -7
- package/dist/domain/changedBehavior.js +2 -3
- package/dist/domain/comparisonSemantics.js +19 -0
- package/dist/domain/completionLedgerGeneration.js +3 -2
- package/dist/domain/conformancePackage.js +2 -1
- package/dist/domain/conformanceTrustGate.js +3 -5
- package/dist/domain/customProtocolCapture.js +2 -2
- package/dist/domain/digests.js +30 -0
- package/dist/domain/dosMz.js +83 -0
- package/dist/domain/electronActiveObservation.js +7 -5
- package/dist/domain/electronObservation.js +3 -2
- package/dist/domain/electronStaticAnalysisNative.js +15 -6
- package/dist/domain/emptyArraySchema.js +3 -0
- package/dist/domain/errors.js +10 -28
- package/dist/domain/evidence.js +5 -3
- package/dist/domain/evidenceCompletionLedger.js +3 -2
- package/dist/domain/functionComparisonNormalization.js +24 -18
- package/dist/domain/functionComparisonResults.js +3 -7
- package/dist/domain/functionComparisonSchemas.js +3 -2
- package/dist/domain/hopperValues.js +108 -8
- package/dist/domain/javascriptApplicationAnalysis.js +4 -7
- package/dist/domain/javascriptApplicationEvidenceSchemas.js +4 -3
- package/dist/domain/javascriptApplicationGraphSchemas.js +8 -7
- package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +9 -7
- package/dist/domain/javascriptApplicationVersionItems.js +12 -18
- package/dist/domain/javascriptAstValues.js +4 -0
- package/dist/domain/javascriptExportShapeComparison.js +1 -6
- package/dist/domain/javascriptExportShapeComparisonSchemas.js +6 -10
- package/dist/domain/javascriptExportShapeVariants.js +15 -2
- package/dist/domain/javascriptFeatureTraceSchemas.js +8 -7
- package/dist/domain/javascriptRuntimeObservation.js +14 -2
- package/dist/domain/javascriptRuntimeReconciliationMatching.js +8 -0
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +4 -2
- package/dist/domain/javascriptRuntimeReconciliationResult.js +6 -4
- package/dist/domain/javascriptRuntimeReconciliationRuntime.js +15 -4
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +19 -18
- package/dist/domain/javascriptRuntimeStaticCandidates.js +18 -6
- package/dist/domain/javascriptSemanticAnalysis.js +57 -19
- package/dist/domain/javascriptSemanticAsyncEffects.js +39 -40
- package/dist/domain/javascriptSemanticCalls.js +46 -27
- package/dist/domain/javascriptSemanticChildProcesses.js +43 -50
- package/dist/domain/javascriptSemanticDataEffectHelpers.js +91 -18
- package/dist/domain/javascriptSemanticDataEffects.js +22 -10
- package/dist/domain/javascriptSemanticGraphSchemas.js +8 -6
- package/dist/domain/javascriptSemanticObjects.js +13 -3
- package/dist/domain/javascriptSemanticProjection.js +144 -38
- package/dist/domain/javascriptSemanticPromises.js +14 -27
- package/dist/domain/javascriptSemanticQuerySchemas.js +6 -9
- package/dist/domain/javascriptSemanticResources.js +2 -5
- package/dist/domain/javascriptSemanticState.js +4 -0
- package/dist/domain/javascriptSemanticTraceSchemas.js +2 -1
- package/dist/domain/javascriptSemanticTraversal.js +13 -5
- package/dist/domain/javascriptSemanticValues.js +10 -9
- package/dist/domain/javascriptSourceParser.js +5 -1
- package/dist/domain/javascriptStaticAnalysisCalls.js +8 -5
- package/dist/domain/javascriptStaticAnalysisHelpers.js +16 -7
- package/dist/domain/keyedArchive.js +181 -0
- package/dist/domain/managedApplicationGraph.js +4 -3
- package/dist/domain/managedArtifact.js +2 -1
- package/dist/domain/managedMemberComparison.js +18 -13
- package/dist/domain/managedMemberComparisonCoverage.js +2 -1
- package/dist/domain/managedMemberComparisonItems.js +27 -7
- package/dist/domain/managedMemberComparisonMatch.js +22 -6
- package/dist/domain/managedNativeVerificationMatch.js +2 -2
- package/dist/domain/managedNativeVerificationSchemas.js +7 -5
- package/dist/domain/managedReconstruction.js +6 -5
- package/dist/domain/nativeApiBoundary.js +7 -0
- package/dist/domain/nativeDataType.js +51 -0
- package/dist/domain/nativeInspection.js +0 -1
- package/dist/domain/nativeInstruction.js +82 -0
- package/dist/domain/nativeInvestigationGraph.js +9 -5
- package/dist/domain/nativeUiObservation.js +123 -0
- package/dist/domain/nativeValueFlow.js +17 -0
- package/dist/domain/nativeValueTrace.js +64 -0
- package/dist/domain/objcSwiftMetadata.js +39 -0
- package/dist/domain/peInspection.js +1 -0
- package/dist/domain/processCapture.js +5 -55
- package/dist/domain/processCaptureExample.js +0 -9
- package/dist/domain/processCaptureValidation.js +13 -144
- package/dist/domain/processComparison.js +3 -25
- package/dist/domain/processObservation.js +0 -29
- package/dist/domain/processScenario.js +28 -228
- package/dist/domain/processTraceDimensionProjection.js +0 -15
- package/dist/domain/processTraceEvaluation.js +0 -6
- package/dist/domain/protocolCapture.js +8 -36
- package/dist/domain/reconstructionCoverage.js +3 -2
- package/dist/domain/reconstructionObligationLedgerSchemas.js +4 -12
- package/dist/domain/reconstructionReadinessSchemas.js +4 -3
- package/dist/domain/reconstructionVerification.js +2 -1
- package/dist/domain/reconstructionVerificationSchemas.js +6 -13
- package/dist/domain/referenceSourceClassification.js +0 -110
- package/dist/domain/referenceSourceGraph.js +15 -5
- package/dist/domain/residualUnknown.js +3 -2
- package/dist/domain/runtimeIdentification.js +6 -5
- package/dist/domain/sourceMapContents.js +5 -0
- package/dist/domain/sourceToBundleComparison.js +3 -10
- package/dist/domain/sourceToBundleComparisonSchemas.js +7 -6
- package/dist/domain/sourceToBundleSignals.js +9 -3
- package/dist/domain/staticRuntimeCorrelation.js +5 -11
- package/dist/domain/webBundleAnalysis.js +17 -9
- package/dist/domain/webBundleAnalyzer.js +1 -1
- package/dist/domain/webCaptureDiff.js +5 -11
- package/dist/domain/webCaptureDiffSchemas.js +2 -1
- package/dist/domain/webMcpDiscovery.js +2 -1
- package/dist/dotnet/ManagedMemberInspectorCore.js +15 -7
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +57 -40
- package/dist/dotnet/ManagedMemberRows.js +2 -0
- package/dist/dotnet/ManagedMethodBodyReader.js +15 -8
- package/dist/dotnet/ManagedPeReader.js +2 -0
- package/dist/generatedMcpToolCatalog.js +1 -1
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +15 -5
- package/dist/ghidra/GhidraClient.js +38 -8
- package/dist/ghidra/GhidraFunctionValues.js +56 -20
- package/dist/ghidra/GhidraInstallation.js +7 -4
- package/dist/ghidra/GhidraInventoryValues.js +44 -9
- package/dist/ghidra/GhidraLauncher.js +18 -3
- package/dist/ghidra/GhidraProvider.js +23 -2
- package/dist/ghidra/GhidraRequestQueue.js +45 -4
- package/dist/ghidra/GhidraSessionValues.js +5 -0
- package/dist/hopper/HopperAnalysisProfile.js +2 -0
- package/dist/hopper/HopperProvider.js +29 -6
- package/dist/hopper/HopperTargetLease.js +18 -4
- package/dist/logger.js +0 -13
- package/dist/main/messages.js +0 -1
- package/dist/main/reload.js +3 -32
- package/dist/main/shutdown.js +1 -2
- package/dist/main/transport.js +0 -17
- package/dist/main.js +0 -10
- package/dist/native/AppleDispatchMetadata.js +582 -0
- package/dist/native/AppleObjcProtocols.js +88 -0
- package/dist/native/AppleSwiftVtables.js +86 -0
- package/dist/native/CommandRunner.js +1 -1
- package/dist/native/NativeHostCapabilities.js +23 -0
- package/dist/native/NativeMacOSProvider.js +61 -9
- package/dist/native/NativeMachoInspection.js +39 -6
- package/dist/native/NativeUiHelperRuntime.js +42 -0
- package/dist/native/NativeUiObservation.js +174 -0
- package/dist/native/parsers/codesign.js +4 -1
- package/dist/native/parsers/dyldInfo.js +51 -25
- package/dist/native/parsers/lipo.js +13 -4
- package/dist/native/parsers/otool.js +84 -39
- package/dist/native/parsers/plist.js +2 -1
- package/dist/process/ExecFileOutput.js +5 -1
- package/dist/process/ProcessOwnership.js +69 -33
- package/dist/process/ProcessOwnershipObservation.js +31 -12
- package/dist/process/ProviderProcess.js +4 -2
- package/dist/reference/ReferenceSourceReaderEntries.js +48 -31
- package/dist/reference/ReferenceSourceReaderErrors.js +24 -0
- package/dist/reference/ReferenceSourceReaderFile.js +11 -5
- package/dist/reference/ReferenceSourceReaderValidate.js +22 -8
- package/dist/server/createServer.js +7 -62
- package/dist/server/registerApplicationTools/helpers.js +2 -9
- package/dist/server/registerApplicationTools.js +0 -4
- package/dist/server/registerArtifactComparisonTool.js +1 -1
- package/dist/server/registerBrowserScenarioTool.js +4 -2
- package/dist/server/registerBrowserTools.js +7 -7
- package/dist/server/registerBundleComparisonTool.js +1 -1
- package/dist/server/registerCloseLifecycleTool.js +1 -1
- package/dist/server/registerElectronTools.js +10 -4
- package/dist/server/registerEnhancedTools.js +20 -12
- package/dist/server/registerEvidenceTools.js +4 -28
- package/dist/server/registerFunctionComparisonTool.js +1 -1
- package/dist/server/registerInvestigationTools.js +6 -6
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -2
- package/dist/server/registerManagedTools.js +28 -14
- package/dist/server/registerManagedWorkflowTools.js +0 -2
- package/dist/server/registerProcessComparisonTool.js +1 -3
- package/dist/server/registerSessionRecordTools.js +9 -9
- package/dist/server/registerSessionStatusTool.js +1 -1
- package/dist/server/registerSessionTools.js +28 -57
- package/dist/server/sessionAvailabilityPolicy.js +2 -3
- package/dist/server/sessionToolPolicies.js +0 -4
- package/dist/server/toolResult.js +8 -10
- package/package.json +32 -22
- package/skills/reverse-engineer-anything/SKILL.md +15 -11
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +3 -2
- package/skills/reverse-engineer-anything/references/javascript-applications.md +3 -2
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +8 -6
- package/skills/reverse-engineer-anything/references/runtime-observation.md +15 -11
- package/dist/application/CommandShimReplay.js +0 -152
- package/dist/application/ConfiguredRoots.js +0 -19
- package/dist/application/InstrumentedJavaScriptReplayHost.js +0 -36
- package/dist/application/JavaScriptReplayPermission.js +0 -16
- package/dist/application/JavaScriptReplayPlanning.js +0 -207
- package/dist/application/JavaScriptReplayService.js +0 -274
- package/dist/application/LoopbackReplay.js +0 -389
- package/dist/application/LoopbackReplayRecorder.js +0 -129
- package/dist/application/ManagedRuntimeCorrelationService.js +0 -104
- package/dist/application/NodeRuntimeCharacterizationService.js +0 -191
- package/dist/application/PermissionAuthority.js +0 -268
- package/dist/application/PermissionConfiguration.js +0 -26
- package/dist/application/PermissionFailure.js +0 -5
- package/dist/application/ProcessCaptureAuthority.js +0 -24
- package/dist/application/ProcessCapturePermission.js +0 -13
- package/dist/application/ProcessCheckpoints.js +0 -178
- package/dist/application/ProcessReactiveCoordinator.js +0 -223
- package/dist/application/ProcessReactiveEffects.js +0 -153
- package/dist/application/ProcessReactiveHarness.js +0 -106
- package/dist/application/ProcessReactiveObservations.js +0 -105
- package/dist/application/ProjectPermissionStore.js +0 -199
- package/dist/application/RuntimeExecutableDiagnostics.js +0 -198
- package/dist/application/Upgrade.js +0 -134
- package/dist/browser/SensitiveTextCapture.js +0 -8
- package/dist/cliPolicyCommands.js +0 -185
- package/dist/config/browserScenario.js +0 -77
- package/dist/config/electronAutomation.js +0 -35
- package/dist/config/javascriptReplay.js +0 -41
- package/dist/config/managedRuntime.js +0 -25
- package/dist/config/passiveObservation.js +0 -87
- package/dist/config/permissions.js +0 -23
- package/dist/config/processCapture.js +0 -47
- package/dist/contracts/replayMachineExample.js +0 -37
- package/dist/domain/javascriptExportInstrumentation.js +0 -95
- package/dist/domain/javascriptReplay.js +0 -360
- package/dist/domain/managedRuntimeCorrelation.js +0 -181
- package/dist/domain/nodeRuntimeCharacterization.js +0 -63
- package/dist/domain/permissionPolicy.js +0 -176
- package/dist/domain/processCaptureReactiveSchema.js +0 -68
- package/dist/domain/processCaptureReactiveValidation.js +0 -180
- package/dist/domain/processReactiveCheckpointDataflow.js +0 -32
- package/dist/domain/processReactiveMatching.js +0 -196
- package/dist/domain/processReactiveRuntime.js +0 -116
- package/dist/domain/processReactiveScenario.js +0 -296
- package/dist/domain/processReactiveScenarioPreflight.js +0 -95
- package/dist/domain/processReactiveTransition.js +0 -187
- package/dist/domain/replayMachine.js +0 -320
- package/dist/domain/replayMachineRun.js +0 -168
- package/dist/domain/replayMachineRuntime.js +0 -296
- package/dist/domain/replayMachineValues.js +0 -84
- package/dist/domain/runtimeCharacterization.js +0 -84
- package/dist/replay/JavaScriptReplayWorker.js +0 -382
- package/dist/replay/JavaScriptReplayWorkerTypes.js +0 -1
- package/dist/replay/LinuxJavaScriptReplayRunner.js +0 -216
- package/dist/replay/LinuxJavaScriptReplaySandbox.js +0 -121
- package/dist/replay/LinuxRuntimeClosure.js +0 -44
- package/dist/replay/LinuxSeccompPolicy.js +0 -40
- package/dist/replay/ReplayOutcome.js +0 -104
- package/dist/replay/ReplayProcessLifecycle.js +0 -96
- package/dist/replay/ReplaySeccompFile.js +0 -29
- package/dist/replay/ReplayWorkerProtocol.js +0 -58
- package/dist/replay/SystemJavaScriptReplayHost.js +0 -153
- package/dist/server/ProcessCaptureElicitation.js +0 -153
- package/dist/server/registerApplicationTools/characterization.js +0 -46
- package/dist/server/registerApplicationTools/controlledReplay.js +0 -31
- package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +0 -29
- package/dist/server/registerReplayMachineTool.js +0 -14
- package/skills/reverse-engineer-anything/references/controlled-replay.md +0 -12
|
@@ -52,7 +52,7 @@ export const parseLipoArchitectures = (output) => {
|
|
|
52
52
|
return architectures;
|
|
53
53
|
};
|
|
54
54
|
const integer = (value) => {
|
|
55
|
-
if (value === undefined)
|
|
55
|
+
if (value === undefined || !/^\d+$/u.test(value))
|
|
56
56
|
return null;
|
|
57
57
|
const parsed = Number.parseInt(value, 10);
|
|
58
58
|
return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : null;
|
|
@@ -60,8 +60,17 @@ const integer = (value) => {
|
|
|
60
60
|
const alignment = (value) => {
|
|
61
61
|
if (value === undefined)
|
|
62
62
|
return null;
|
|
63
|
-
const exponent =
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
const exponent = /^2\^(\d+)(?: \((\d+)\))?$/u.exec(value);
|
|
64
|
+
const powerText = exponent?.[1];
|
|
65
|
+
if (powerText !== undefined) {
|
|
66
|
+
const power = Number.parseInt(powerText, 10);
|
|
67
|
+
if (power > 52)
|
|
68
|
+
return null;
|
|
69
|
+
const alignment = 2 ** power;
|
|
70
|
+
const reported = exponent?.[2];
|
|
71
|
+
return reported === undefined || integer(reported) === alignment
|
|
72
|
+
? alignment
|
|
73
|
+
: null;
|
|
74
|
+
}
|
|
66
75
|
return integer(value);
|
|
67
76
|
};
|
|
@@ -1,11 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* otool emits LF, but a capture replayed from another host or toolchain can
|
|
3
|
+
* carry CRLF. The section/command boundaries below match a bare `\n`, so a
|
|
4
|
+
* stray `\r` would swallow the terminator and silently empty `sections` while
|
|
5
|
+
* leaking section fields into the command. Normalizing once at the boundary
|
|
6
|
+
* keeps every parser below working on one line ending.
|
|
7
|
+
*/
|
|
8
|
+
const normalizeLineEndings = (output) => output.replaceAll("\r\n", "\n");
|
|
1
9
|
/** Parse stable fields from `otool -l`, preserving unknown command fields. */
|
|
2
|
-
export const parseOtoolLoadCommands = (
|
|
3
|
-
const
|
|
4
|
-
const
|
|
10
|
+
export const parseOtoolLoadCommands = (raw) => {
|
|
11
|
+
const output = normalizeLineEndings(raw);
|
|
12
|
+
const header = parseHeader(output);
|
|
13
|
+
const state = createLoadCommandState(header?.flags);
|
|
5
14
|
for (const block of output.split(/(?=Load command \d+)/u))
|
|
6
15
|
parseLoadCommand(block, state);
|
|
7
16
|
return {
|
|
8
|
-
fileType:
|
|
17
|
+
fileType: header?.fileType ?? null,
|
|
9
18
|
flags: [...state.flags].sort(),
|
|
10
19
|
uuid: state.uuid,
|
|
11
20
|
commands: state.commands,
|
|
@@ -15,19 +24,42 @@ export const parseOtoolLoadCommands = (output) => {
|
|
|
15
24
|
builds: state.builds,
|
|
16
25
|
};
|
|
17
26
|
};
|
|
18
|
-
const
|
|
19
|
-
.split(/\r?\n/u)
|
|
20
|
-
.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
27
|
+
const parseHeader = (output) => {
|
|
28
|
+
const lines = output.split(/\r?\n/u).map((line) => line.trim());
|
|
29
|
+
const columnsLine = lines.findIndex((line) => /(?:^|\s)magic\s/u.test(line));
|
|
30
|
+
if (columnsLine < 0)
|
|
31
|
+
return undefined;
|
|
32
|
+
const columns = lines[columnsLine]?.split(/\s+/u);
|
|
33
|
+
const dataLine = lines.slice(columnsLine + 1).find((line) => line.length > 0);
|
|
34
|
+
const values = dataLine?.split(/\s+/u);
|
|
35
|
+
if (columns === undefined || values === undefined)
|
|
36
|
+
return undefined;
|
|
37
|
+
const fileTypeIndex = columns.indexOf("filetype");
|
|
38
|
+
const flagsIndex = columns.indexOf("flags");
|
|
39
|
+
const complete = values.length >= columns.length;
|
|
40
|
+
const fileTypeValueIndex = flagsIndex >= 0 && fileTypeIndex > flagsIndex
|
|
41
|
+
? values.length - (columns.length - fileTypeIndex)
|
|
42
|
+
: fileTypeIndex;
|
|
43
|
+
const flagsEnd = flagsIndex >= 0 ? values.length - (columns.length - flagsIndex - 1) : 0;
|
|
44
|
+
return {
|
|
45
|
+
fileType: complete && fileTypeValueIndex >= 0 && fileTypeValueIndex < values.length
|
|
46
|
+
? (values[fileTypeValueIndex] ?? null)
|
|
47
|
+
: null,
|
|
48
|
+
flags: !complete || flagsIndex < 0 || flagsIndex >= flagsEnd
|
|
49
|
+
? []
|
|
50
|
+
: values
|
|
51
|
+
.slice(flagsIndex, flagsEnd)
|
|
52
|
+
.filter((value) => value.length > 0),
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
const createLoadCommandState = (headerFlags) => ({
|
|
24
56
|
commands: [],
|
|
25
57
|
segments: [],
|
|
26
58
|
dependencies: [],
|
|
27
59
|
entrypoints: [],
|
|
28
60
|
builds: [],
|
|
29
61
|
uuid: null,
|
|
30
|
-
flags: new Set(
|
|
62
|
+
flags: new Set(headerFlags ?? []),
|
|
31
63
|
});
|
|
32
64
|
const parseLoadCommand = (block, state) => {
|
|
33
65
|
const indexText = /^Load command (\d+)/u.exec(block)?.[1];
|
|
@@ -39,7 +71,6 @@ const parseLoadCommand = (block, state) => {
|
|
|
39
71
|
state.commands.push({
|
|
40
72
|
index: Number.parseInt(indexText, 10),
|
|
41
73
|
kind,
|
|
42
|
-
file_offset: null,
|
|
43
74
|
fields,
|
|
44
75
|
});
|
|
45
76
|
collectUuid(kind, fields, state);
|
|
@@ -47,7 +78,6 @@ const parseLoadCommand = (block, state) => {
|
|
|
47
78
|
collectBuild(kind, block, fields, state);
|
|
48
79
|
collectDependency(kind, fields, state);
|
|
49
80
|
collectSegment(kind, block, fields, state);
|
|
50
|
-
collectFlags(fields, state.flags);
|
|
51
81
|
};
|
|
52
82
|
const collectUuid = (kind, fields, state) => {
|
|
53
83
|
if (kind === "LC_UUID")
|
|
@@ -61,17 +91,28 @@ const collectEntrypoint = (kind, fields, state) => {
|
|
|
61
91
|
state.entrypoints.push({ file_offset: entry });
|
|
62
92
|
};
|
|
63
93
|
const collectBuild = (kind, block, fields, state) => {
|
|
64
|
-
if (kind
|
|
94
|
+
if (kind === "LC_BUILD_VERSION") {
|
|
95
|
+
state.builds.push({
|
|
96
|
+
platform: stringField(fields, "platform"),
|
|
97
|
+
minimum_os: stringField(fields, "minos"),
|
|
98
|
+
sdk: stringField(fields, "sdk"),
|
|
99
|
+
tools: parseBuildTools(block),
|
|
100
|
+
});
|
|
65
101
|
return;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
102
|
+
}
|
|
103
|
+
if (kind.startsWith("LC_VERSION_MIN_"))
|
|
104
|
+
state.builds.push({
|
|
105
|
+
platform: kind.slice("LC_VERSION_MIN_".length) || null,
|
|
106
|
+
minimum_os: stringField(fields, "version"),
|
|
107
|
+
sdk: stringField(fields, "sdk"),
|
|
108
|
+
tools: [],
|
|
109
|
+
});
|
|
72
110
|
};
|
|
73
111
|
const collectDependency = (kind, fields, state) => {
|
|
74
|
-
if (!kind.startsWith("LC_LOAD_") &&
|
|
112
|
+
if (!kind.startsWith("LC_LOAD_") &&
|
|
113
|
+
kind !== "LC_ID_DYLIB" &&
|
|
114
|
+
kind !== "LC_REEXPORT_DYLIB" &&
|
|
115
|
+
kind !== "LC_LAZY_LOAD_DYLIB")
|
|
75
116
|
return;
|
|
76
117
|
state.dependencies.push({
|
|
77
118
|
path: stripOffsetSuffix(stringField(fields, "name")),
|
|
@@ -84,19 +125,15 @@ const collectSegment = (kind, block, fields, state) => {
|
|
|
84
125
|
if (kind === "LC_SEGMENT" || kind === "LC_SEGMENT_64")
|
|
85
126
|
state.segments.push(parseSegment(block, fields));
|
|
86
127
|
};
|
|
87
|
-
const collectFlags = (fields, flags) => {
|
|
88
|
-
const rawFlags = stringField(fields, "flags");
|
|
89
|
-
if (rawFlags === null)
|
|
90
|
-
return;
|
|
91
|
-
for (const flag of rawFlags.split(/\s+/u))
|
|
92
|
-
if (flag.length > 0)
|
|
93
|
-
flags.add(flag);
|
|
94
|
-
};
|
|
95
128
|
const parseFields = (block) => {
|
|
96
129
|
const fields = {};
|
|
97
130
|
for (const rawLine of block.split(/\r?\n/u).slice(1)) {
|
|
98
131
|
const line = rawLine.trim();
|
|
99
|
-
|
|
132
|
+
// Keys are `token` or a compound `token version`. `time stamp` is the one
|
|
133
|
+
// other real key, and it must be matched as a whole: treating `stamp` as a
|
|
134
|
+
// generic suffix would swallow an install name such as
|
|
135
|
+
// `name stamp plugin.dylib`, hiding the dependency path behind `unknown`.
|
|
136
|
+
const match = /^((?:time stamp)|\S+(?:\s+version)?)\s+(.+)$/u.exec(line);
|
|
100
137
|
if (match?.[1] === undefined || match[2] === undefined)
|
|
101
138
|
continue;
|
|
102
139
|
const value = match[2].trim();
|
|
@@ -125,7 +162,7 @@ const parseSections = (block) => block
|
|
|
125
162
|
address: hexField(fields, "addr"),
|
|
126
163
|
size: numberField(fields, "size"),
|
|
127
164
|
file_offset: numberField(fields, "offset"),
|
|
128
|
-
alignment: sectionAlignment(
|
|
165
|
+
alignment: sectionAlignment(stringField(fields, "align")),
|
|
129
166
|
flags: (stringField(fields, "flags") ?? "")
|
|
130
167
|
.split(/\s+/u)
|
|
131
168
|
.filter((flag) => flag.length > 0),
|
|
@@ -148,9 +185,9 @@ const permissions = (raw) => {
|
|
|
148
185
|
const numericValue = numeric(raw);
|
|
149
186
|
if (numericValue !== null)
|
|
150
187
|
return {
|
|
151
|
-
read: (numericValue &
|
|
188
|
+
read: (numericValue & 1) !== 0,
|
|
152
189
|
write: (numericValue & 2) !== 0,
|
|
153
|
-
execute: (numericValue &
|
|
190
|
+
execute: (numericValue & 4) !== 0,
|
|
154
191
|
raw,
|
|
155
192
|
};
|
|
156
193
|
if (/^[r-][w-][x-]$/u.test(raw))
|
|
@@ -162,11 +199,12 @@ const permissions = (raw) => {
|
|
|
162
199
|
};
|
|
163
200
|
return { read: null, write: null, execute: null, raw };
|
|
164
201
|
};
|
|
202
|
+
/** A whole decimal or hexadecimal integer literal, with no surrounding text. */
|
|
203
|
+
const NUMERIC_PATTERN = /^(?:0x[a-fA-F0-9]+|\d+)$/u;
|
|
165
204
|
const numeric = (value) => {
|
|
166
|
-
|
|
167
|
-
if (token === undefined || !/^(?:0x[a-fA-F0-9]+|\d+)$/u.test(token))
|
|
205
|
+
if (!NUMERIC_PATTERN.test(value))
|
|
168
206
|
return null;
|
|
169
|
-
const parsed = Number.parseInt(
|
|
207
|
+
const parsed = Number.parseInt(value, value.startsWith("0x") ? 16 : 10);
|
|
170
208
|
return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : null;
|
|
171
209
|
};
|
|
172
210
|
const stringField = (fields, name) => {
|
|
@@ -186,8 +224,15 @@ const numberField = (fields, name) => {
|
|
|
186
224
|
: null;
|
|
187
225
|
};
|
|
188
226
|
const hexField = (fields, name) => {
|
|
189
|
-
const value =
|
|
190
|
-
|
|
227
|
+
const value = stringField(fields, name);
|
|
228
|
+
if (value === null || !NUMERIC_PATTERN.test(value))
|
|
229
|
+
return null;
|
|
230
|
+
return `0x${BigInt(value).toString(16)}`;
|
|
191
231
|
};
|
|
192
232
|
const stripOffsetSuffix = (value) => value?.replace(/\s+\(offset\s+\d+\)$/u, "") ?? "unknown";
|
|
193
|
-
const sectionAlignment = (
|
|
233
|
+
const sectionAlignment = (raw) => {
|
|
234
|
+
if (raw === null)
|
|
235
|
+
return null;
|
|
236
|
+
const exponent = numeric(/^2\^(\d+)(?:\s+\(\d+\))?$/u.exec(raw)?.[1] ?? raw);
|
|
237
|
+
return exponent === null || exponent > 52 ? null : 2 ** exponent;
|
|
238
|
+
};
|
|
@@ -2,7 +2,8 @@ import { z } from "zod";
|
|
|
2
2
|
const plistObject = z.record(z.string(), z.unknown());
|
|
3
3
|
/** Parse plutil JSON output and project stable bundle metadata. */
|
|
4
4
|
export const parsePlistJson = (output) => {
|
|
5
|
-
|
|
5
|
+
// plutil output can carry a UTF-8 BOM, which JSON.parse rejects outright.
|
|
6
|
+
const value = JSON.parse(output.replace(/^\uFEFF/u, ""));
|
|
6
7
|
const object = plistObject.safeParse(value);
|
|
7
8
|
const field = (name) => {
|
|
8
9
|
if (!object.success)
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { execFile, } from "node:child_process";
|
|
2
2
|
/** Run a shell-free command while capturing its complete UTF-8 output. */
|
|
3
3
|
export const execFileOutput = (command, arguments_, options = {}) => new Promise((resolve, reject) => {
|
|
4
|
-
execFile(command, [...arguments_], {
|
|
4
|
+
execFile(command, [...arguments_], {
|
|
5
|
+
...options,
|
|
6
|
+
encoding: "utf8",
|
|
7
|
+
maxBuffer: options.maxBuffer ?? Number.POSITIVE_INFINITY,
|
|
8
|
+
}, (error, stdout, stderr) => {
|
|
5
9
|
if (error !== null) {
|
|
6
10
|
reject(error);
|
|
7
11
|
return;
|
|
@@ -48,14 +48,13 @@ export const parseProcessEnvironment = (value) => Object.fromEntries(value
|
|
|
48
48
|
const separator = entry.indexOf("=");
|
|
49
49
|
return [entry.slice(0, separator), entry.slice(separator + 1)];
|
|
50
50
|
}));
|
|
51
|
-
|
|
51
|
+
/** Create the operating-system process inspector for an explicit host context. */
|
|
52
|
+
export const createSystemProcessOwnershipHost = (platform = process.platform, hostEnvironment = process.env) => ({
|
|
53
|
+
platform,
|
|
52
54
|
async listProcesses() {
|
|
53
|
-
if (
|
|
55
|
+
if (platform === "win32")
|
|
54
56
|
return [];
|
|
55
|
-
const { stdout } = await execFileOutput("ps", [
|
|
56
|
-
"-axo",
|
|
57
|
-
"pid=,ppid=,pgid=,stat=,command=",
|
|
58
|
-
]);
|
|
57
|
+
const { stdout } = await execFileOutput("ps", ["-axo", "pid=,ppid=,pgid=,stat=,command="], { env: hostEnvironment });
|
|
59
58
|
return stdout
|
|
60
59
|
.split("\n")
|
|
61
60
|
.map((line) => /\s*(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(.*)/u.exec(line))
|
|
@@ -69,22 +68,24 @@ const systemHost = {
|
|
|
69
68
|
}));
|
|
70
69
|
},
|
|
71
70
|
async environment(pid) {
|
|
72
|
-
if (
|
|
71
|
+
if (platform === "linux")
|
|
73
72
|
return parseProcessEnvironment(await readFile(`/proc/${pid}/environ`, "utf8"));
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
const { stdout } = await execFileOutput("ps", ["eww", "-p", String(pid)], {
|
|
74
|
+
env: hostEnvironment,
|
|
75
|
+
});
|
|
76
|
+
const observedEnvironment = {};
|
|
77
77
|
for (const match of stdout.matchAll(/(?:^|\s)([A-Za-z_][A-Za-z0-9_]*)=([^\s]*)/gu)) {
|
|
78
78
|
const name = match[1];
|
|
79
79
|
if (name !== undefined)
|
|
80
|
-
|
|
80
|
+
observedEnvironment[name] = match[2] ?? "";
|
|
81
81
|
}
|
|
82
|
-
return
|
|
82
|
+
return observedEnvironment;
|
|
83
83
|
},
|
|
84
84
|
signalGroup(processGroupId, signal) {
|
|
85
85
|
process.kill(-processGroupId, signal);
|
|
86
86
|
},
|
|
87
|
-
};
|
|
87
|
+
});
|
|
88
|
+
const systemHost = createSystemProcessOwnershipHost();
|
|
88
89
|
const systemWindowsProcessTreeHost = {
|
|
89
90
|
async terminateTree(rootPid) {
|
|
90
91
|
try {
|
|
@@ -104,10 +105,13 @@ const systemWindowsProcessTreeHost = {
|
|
|
104
105
|
export const readProcessRunId = async (pid, host = systemHost) => (await host.environment(pid)).REA_PROCESS_RUN_ID;
|
|
105
106
|
/** Token-validate every rooted POSIX process group before signaling any. */
|
|
106
107
|
export const cleanupOwnedProcessGroup = async (ownership, host = systemHost) => {
|
|
107
|
-
const
|
|
108
|
-
if (
|
|
109
|
-
return {
|
|
110
|
-
|
|
108
|
+
const processTable = await readLiveProcessTable(host);
|
|
109
|
+
if (!processTable.available)
|
|
110
|
+
return {
|
|
111
|
+
cleaned: false,
|
|
112
|
+
reason: `process table could not be inspected: ${processTable.reason}`,
|
|
113
|
+
};
|
|
114
|
+
const plan = await createOwnedCleanupPlan(ownership, processTable.processes, host);
|
|
111
115
|
if ("cleaned" in plan)
|
|
112
116
|
return plan;
|
|
113
117
|
let signaled = false;
|
|
@@ -124,17 +128,23 @@ export const cleanupOwnedProcessGroup = async (ownership, host = systemHost) =>
|
|
|
124
128
|
catch (cause) {
|
|
125
129
|
const code = cause instanceof Error && "code" in cause ? cause.code : undefined;
|
|
126
130
|
if (code !== "ESRCH")
|
|
127
|
-
return {
|
|
131
|
+
return {
|
|
132
|
+
cleaned: false,
|
|
133
|
+
reason: `owned process group signal failed: ${errorMessage(cause)}`,
|
|
134
|
+
};
|
|
128
135
|
}
|
|
129
136
|
}
|
|
130
137
|
return { cleaned: true, signaled };
|
|
131
138
|
};
|
|
132
139
|
/** Verify that no live process still carries an owned capture run token. */
|
|
133
140
|
export const verifyNoTokenOwnedProcesses = async (runId, host = systemHost) => {
|
|
134
|
-
const
|
|
135
|
-
if (
|
|
136
|
-
return {
|
|
137
|
-
|
|
141
|
+
const processTable = await readLiveProcessTable(host);
|
|
142
|
+
if (!processTable.available)
|
|
143
|
+
return {
|
|
144
|
+
cleaned: false,
|
|
145
|
+
reason: `process table could not be inspected: ${processTable.reason}`,
|
|
146
|
+
};
|
|
147
|
+
const scan = await scanTokenOwnedProcesses(processTable.processes, runId, host);
|
|
138
148
|
if (scan.failures.length > 0)
|
|
139
149
|
return cleanupValidationFailure(scan.failures);
|
|
140
150
|
return scan.owned.length === 0
|
|
@@ -143,10 +153,13 @@ export const verifyNoTokenOwnedProcesses = async (runId, host = systemHost) => {
|
|
|
143
153
|
};
|
|
144
154
|
const readLiveProcessTable = async (host) => {
|
|
145
155
|
try {
|
|
146
|
-
return
|
|
156
|
+
return {
|
|
157
|
+
available: true,
|
|
158
|
+
processes: liveProcesses(await host.listProcesses()),
|
|
159
|
+
};
|
|
147
160
|
}
|
|
148
|
-
catch {
|
|
149
|
-
return
|
|
161
|
+
catch (cause) {
|
|
162
|
+
return { available: false, reason: errorMessage(cause) };
|
|
150
163
|
}
|
|
151
164
|
};
|
|
152
165
|
const createOwnedCleanupPlan = async (ownership, processes, host) => {
|
|
@@ -201,10 +214,10 @@ const revalidateOwnedProcessGroup = async (processGroupId, ownership, host) => {
|
|
|
201
214
|
try {
|
|
202
215
|
members = liveProcesses(await host.listProcesses()).filter(({ processGroupId: observedGroupId }) => observedGroupId === processGroupId);
|
|
203
216
|
}
|
|
204
|
-
catch {
|
|
217
|
+
catch (cause) {
|
|
205
218
|
return {
|
|
206
219
|
cleaned: false,
|
|
207
|
-
reason:
|
|
220
|
+
reason: `process ownership could not be revalidated: ${errorMessage(cause)}`,
|
|
208
221
|
};
|
|
209
222
|
}
|
|
210
223
|
const failures = await processOwnershipFailures(members, ownership.runId, host);
|
|
@@ -242,14 +255,25 @@ const processOwnershipFailures = async (members, runId, host) => {
|
|
|
242
255
|
if ((await host.environment(member.pid)).REA_PROCESS_RUN_ID !== runId)
|
|
243
256
|
failures.push({ pid: member.pid, reason: "run-token-mismatch" });
|
|
244
257
|
}
|
|
245
|
-
catch {
|
|
258
|
+
catch (cause) {
|
|
246
259
|
try {
|
|
247
260
|
const live = liveProcesses(await host.listProcesses());
|
|
248
261
|
if (!live.some(({ pid }) => pid === member.pid))
|
|
249
262
|
continue;
|
|
250
263
|
}
|
|
251
|
-
catch {
|
|
252
|
-
|
|
264
|
+
catch (recheckCause) {
|
|
265
|
+
failures.push({
|
|
266
|
+
pid: member.pid,
|
|
267
|
+
reason: "environment-unreadable",
|
|
268
|
+
diagnostic: `${errorMessage(cause)}; process liveness recheck failed: ${errorMessage(recheckCause)}`,
|
|
269
|
+
});
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
failures.push({
|
|
273
|
+
pid: member.pid,
|
|
274
|
+
reason: "environment-unreadable",
|
|
275
|
+
diagnostic: errorMessage(cause),
|
|
276
|
+
});
|
|
253
277
|
}
|
|
254
278
|
}
|
|
255
279
|
return failures;
|
|
@@ -262,18 +286,30 @@ const scanTokenOwnedProcesses = async (processes, runId, host) => {
|
|
|
262
286
|
if ((await host.environment(process.pid)).REA_PROCESS_RUN_ID === runId)
|
|
263
287
|
owned.push(process);
|
|
264
288
|
}
|
|
265
|
-
catch {
|
|
289
|
+
catch (cause) {
|
|
266
290
|
try {
|
|
267
291
|
const live = liveProcesses(await host.listProcesses());
|
|
268
292
|
if (!live.some(({ pid }) => pid === process.pid))
|
|
269
293
|
continue;
|
|
270
294
|
}
|
|
271
|
-
catch {
|
|
272
|
-
|
|
295
|
+
catch (recheckCause) {
|
|
296
|
+
failures.push({
|
|
297
|
+
pid: process.pid,
|
|
298
|
+
reason: "environment-unreadable",
|
|
299
|
+
diagnostic: `${errorMessage(cause)}; process liveness recheck failed: ${errorMessage(recheckCause)}`,
|
|
300
|
+
});
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
failures.push({
|
|
304
|
+
pid: process.pid,
|
|
305
|
+
reason: "environment-unreadable",
|
|
306
|
+
diagnostic: errorMessage(cause),
|
|
307
|
+
});
|
|
273
308
|
}
|
|
274
309
|
}
|
|
275
310
|
return { owned, failures };
|
|
276
311
|
};
|
|
312
|
+
const errorMessage = (cause) => cause instanceof Error ? cause.message : String(cause);
|
|
277
313
|
/** Observe one group without signaling it, failing closed on identity doubt. */
|
|
278
314
|
export const observeOwnedProcessGroup = async (ownership, host = systemHost) => observeOwnedProcessGroupWithHost(ownership, host);
|
|
279
315
|
/**
|
|
@@ -6,10 +6,10 @@ export const observeOwnedProcessGroupWithHost = async (ownership, host) => {
|
|
|
6
6
|
try {
|
|
7
7
|
members = (await host.listProcesses()).filter(({ processGroupId }) => processGroupId === ownership.processGroupId);
|
|
8
8
|
}
|
|
9
|
-
catch {
|
|
9
|
+
catch (cause) {
|
|
10
10
|
return {
|
|
11
11
|
state: "unverifiable",
|
|
12
|
-
reason:
|
|
12
|
+
reason: `process group could not be inspected: ${errorMessage(cause)}`,
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
15
|
const liveMembers = liveProcesses(members);
|
|
@@ -24,11 +24,13 @@ export const observeOwnedProcessGroupWithHost = async (ownership, host) => {
|
|
|
24
24
|
reason: "process ownership did not match",
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
-
catch {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
catch (cause) {
|
|
28
|
+
if (!(await processIsGone(host, member.pid))) {
|
|
29
|
+
return {
|
|
30
|
+
state: "unverifiable",
|
|
31
|
+
reason: `process ownership could not be revalidated for PID ${member.pid}: ${errorMessage(cause)}`,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
36
|
return { state: "alive" };
|
|
@@ -39,8 +41,8 @@ export const observeOwnedProcessLineageWithHost = async (ownership, host) => {
|
|
|
39
41
|
try {
|
|
40
42
|
processes = liveProcesses(await host.listProcesses());
|
|
41
43
|
}
|
|
42
|
-
catch {
|
|
43
|
-
return unavailableLineage(ownership,
|
|
44
|
+
catch (cause) {
|
|
45
|
+
return unavailableLineage(ownership, `process table could not be inspected: ${errorMessage(cause)}`);
|
|
44
46
|
}
|
|
45
47
|
const launcher = processes.find(({ pid }) => pid === ownership.leaderPid);
|
|
46
48
|
if (launcher === undefined)
|
|
@@ -49,14 +51,22 @@ export const observeOwnedProcessLineageWithHost = async (ownership, host) => {
|
|
|
49
51
|
if (identityFailure !== null)
|
|
50
52
|
return unavailableLineage(ownership, identityFailure);
|
|
51
53
|
const descendants = descendantsOf(launcher.pid, processes);
|
|
54
|
+
const verifiedDescendants = [];
|
|
52
55
|
for (const member of [launcher, ...descendants]) {
|
|
53
56
|
try {
|
|
54
57
|
if ((await host.environment(member.pid)).REA_PROCESS_RUN_ID !==
|
|
55
58
|
ownership.runId)
|
|
56
59
|
return unavailableLineage(ownership, "process lineage contains an unowned or PID-reused process");
|
|
60
|
+
if (member.pid !== launcher.pid)
|
|
61
|
+
verifiedDescendants.push(member);
|
|
57
62
|
}
|
|
58
|
-
catch {
|
|
59
|
-
|
|
63
|
+
catch (cause) {
|
|
64
|
+
if (await processIsGone(host, member.pid)) {
|
|
65
|
+
if (member.pid === launcher.pid)
|
|
66
|
+
return unavailableLineage(ownership, "owned launcher exited during lineage validation");
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
return unavailableLineage(ownership, `process ownership could not be revalidated for PID ${member.pid}: ${errorMessage(cause)}`);
|
|
60
70
|
}
|
|
61
71
|
}
|
|
62
72
|
return {
|
|
@@ -67,7 +77,7 @@ export const observeOwnedProcessLineageWithHost = async (ownership, host) => {
|
|
|
67
77
|
launcherPid: launcher.pid,
|
|
68
78
|
launcherParentPid: launcher.parentPid,
|
|
69
79
|
processGroupId: launcher.processGroupId,
|
|
70
|
-
descendants:
|
|
80
|
+
descendants: verifiedDescendants
|
|
71
81
|
.sort((left, right) => left.pid - right.pid)
|
|
72
82
|
.map(({ pid, parentPid, processGroupId }) => ({
|
|
73
83
|
pid,
|
|
@@ -85,3 +95,12 @@ const unavailableLineage = (ownership, reason) => ({
|
|
|
85
95
|
processGroupId: ownership.processGroupId,
|
|
86
96
|
reason,
|
|
87
97
|
});
|
|
98
|
+
const processIsGone = async (host, pid) => {
|
|
99
|
+
try {
|
|
100
|
+
return !liveProcesses(await host.listProcesses()).some((process) => process.pid === pid);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
const errorMessage = (cause) => cause instanceof Error ? cause.message : String(cause);
|
|
@@ -8,14 +8,16 @@ const DEFAULT_KILL_GRACE_MS = 1_000;
|
|
|
8
8
|
* selecting provider-specific command arguments or environment values.
|
|
9
9
|
*/
|
|
10
10
|
export const spawnOwnedProviderProcess = async (options) => {
|
|
11
|
+
const platform = options.platform ?? process.platform;
|
|
12
|
+
const hostEnvironment = options.hostEnvironment ?? process.env;
|
|
11
13
|
const child = spawn(options.command, [...options.arguments], {
|
|
12
14
|
shell: false,
|
|
13
15
|
windowsHide: true,
|
|
14
16
|
stdio: ["ignore", "pipe", "pipe"],
|
|
15
|
-
detached:
|
|
17
|
+
detached: platform !== "win32",
|
|
16
18
|
windowsVerbatimArguments: options.windowsVerbatimArguments ?? false,
|
|
17
19
|
env: {
|
|
18
|
-
...
|
|
20
|
+
...hostEnvironment,
|
|
19
21
|
...options.env,
|
|
20
22
|
REA_PROCESS_RUN_ID: options.runId,
|
|
21
23
|
},
|