rea-agents 3.2.1 → 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
|
@@ -3,6 +3,7 @@ import { semanticCallableIdForNode, semanticStaticPropertyName, } from "./javasc
|
|
|
3
3
|
import { resolveSemanticBindingState, semanticResolutionBlocked, } from "./javascriptSemanticState.js";
|
|
4
4
|
import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
|
|
5
5
|
import { range } from "./javascriptStaticAnalysisHelpers.js";
|
|
6
|
+
import { dataEffectLiteralString, dataEffectMemberCallee, assignedSemanticResultBindings, scalarAssignedResultBinding, semanticProjectedBindingFacts, } from "./javascriptSemanticDataEffectHelpers.js";
|
|
6
7
|
const EVENT_REGISTER_METHODS = [
|
|
7
8
|
"on",
|
|
8
9
|
"once",
|
|
@@ -36,19 +37,28 @@ export const collectJavaScriptSemanticAsyncEffects = (program, state, callables)
|
|
|
36
37
|
const timers = [];
|
|
37
38
|
const callableIds = new Set(callables.map(({ callableId }) => callableId));
|
|
38
39
|
const callableStack = [];
|
|
40
|
+
const ancestors = [];
|
|
39
41
|
traverseJavaScriptAst(program, {
|
|
40
|
-
enter: (node
|
|
42
|
+
enter: (node) => {
|
|
41
43
|
const callableId = semanticCallableIdForNode(node);
|
|
42
44
|
if (callableId !== null && callableIds.has(callableId))
|
|
43
45
|
callableStack.push(callableId);
|
|
44
|
-
if (
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
if (t.isCallExpression(node) || t.isOptionalCallExpression(node)) {
|
|
47
|
+
const ownerCallableId = callableStack.at(-1) ?? null;
|
|
48
|
+
collectEvent(node, ownerCallableId, state, events);
|
|
49
|
+
collectTimer({
|
|
50
|
+
node,
|
|
51
|
+
ownerCallableId,
|
|
52
|
+
state,
|
|
53
|
+
output: timers,
|
|
54
|
+
ancestors,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
ancestors.push(node);
|
|
49
58
|
},
|
|
50
59
|
exit: (node) => {
|
|
51
60
|
const callableId = semanticCallableIdForNode(node);
|
|
61
|
+
ancestors.pop();
|
|
52
62
|
if (callableId !== null && callableStack.at(-1) === callableId)
|
|
53
63
|
callableStack.pop();
|
|
54
64
|
},
|
|
@@ -59,7 +69,7 @@ export const collectJavaScriptSemanticAsyncEffects = (program, state, callables)
|
|
|
59
69
|
};
|
|
60
70
|
};
|
|
61
71
|
const collectEvent = (node, ownerCallableId, state, output) => {
|
|
62
|
-
const member =
|
|
72
|
+
const member = dataEffectMemberCallee(node);
|
|
63
73
|
if (member === null)
|
|
64
74
|
return;
|
|
65
75
|
const method = EVENT_METHODS.find((candidate) => candidate ===
|
|
@@ -70,7 +80,7 @@ const collectEvent = (node, ownerCallableId, state, output) => {
|
|
|
70
80
|
const eventArgument = node.arguments[0];
|
|
71
81
|
const listenerArgument = node.arguments[1];
|
|
72
82
|
const emitter = emitterIdentity(member.object, state);
|
|
73
|
-
const eventName =
|
|
83
|
+
const eventName = dataEffectLiteralString(eventArgument);
|
|
74
84
|
output.push({
|
|
75
85
|
eventId: `event:${kind}:${String(node.start ?? -1)}:${String(node.end ?? -1)}`,
|
|
76
86
|
kind,
|
|
@@ -122,31 +132,43 @@ const emitterIdentity = (node, state) => {
|
|
|
122
132
|
};
|
|
123
133
|
};
|
|
124
134
|
const collectTimer = (input) => {
|
|
125
|
-
const { node,
|
|
135
|
+
const { node, ownerCallableId, state, output, ancestors } = input;
|
|
126
136
|
const method = timerMethod(node.callee, state);
|
|
127
137
|
if (method === null)
|
|
128
138
|
return;
|
|
129
139
|
const kind = TIMER_SCHEDULE_METHODS.some((candidate) => candidate === method)
|
|
130
140
|
? "schedule"
|
|
131
141
|
: "cancel";
|
|
142
|
+
const projectedResultBindings = assignedSemanticResultBindings(node, ancestors, state);
|
|
132
143
|
output.push({
|
|
133
144
|
node,
|
|
134
145
|
method,
|
|
135
146
|
kind,
|
|
136
147
|
ownerCallableId,
|
|
137
148
|
handleBindingId: kind === "schedule"
|
|
138
|
-
?
|
|
149
|
+
? scalarAssignedResultBinding(projectedResultBindings)
|
|
139
150
|
: bindingId(node.arguments[0], state),
|
|
151
|
+
projectedResultBindings: kind === "schedule"
|
|
152
|
+
? semanticProjectedBindingFacts(projectedResultBindings.filter(({ projectionPath }) => projectionPath.length > 0))
|
|
153
|
+
: [],
|
|
140
154
|
});
|
|
141
155
|
};
|
|
142
156
|
const resolveTimers = (candidates) => {
|
|
143
157
|
const schedulesByBinding = new Map();
|
|
144
158
|
for (const candidate of candidates) {
|
|
145
|
-
if (candidate.kind !== "schedule"
|
|
159
|
+
if (candidate.kind !== "schedule")
|
|
146
160
|
continue;
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
161
|
+
const ids = [
|
|
162
|
+
...(candidate.handleBindingId === null
|
|
163
|
+
? []
|
|
164
|
+
: [candidate.handleBindingId]),
|
|
165
|
+
...candidate.projectedResultBindings.map(({ bindingId }) => bindingId),
|
|
166
|
+
];
|
|
167
|
+
for (const id of ids) {
|
|
168
|
+
const existing = schedulesByBinding.get(id) ?? [];
|
|
169
|
+
existing.push(candidate);
|
|
170
|
+
schedulesByBinding.set(id, existing);
|
|
171
|
+
}
|
|
150
172
|
}
|
|
151
173
|
return candidates.map((candidate) => {
|
|
152
174
|
const linked = candidate.kind === "cancel" && candidate.handleBindingId !== null
|
|
@@ -159,13 +181,15 @@ const resolveTimers = (candidates) => {
|
|
|
159
181
|
location: range(candidate.node),
|
|
160
182
|
ownerCallableId: candidate.ownerCallableId,
|
|
161
183
|
handleBindingId: candidate.handleBindingId,
|
|
184
|
+
projectedResultBindings: candidate.projectedResultBindings,
|
|
162
185
|
linkedTimerId: linked.length === 1 && linked[0] !== undefined
|
|
163
186
|
? timerId(linked[0])
|
|
164
187
|
: null,
|
|
165
188
|
delayMilliseconds: timerDelay(candidate),
|
|
166
189
|
resolution: candidate.kind === "schedule"
|
|
167
190
|
? "complete"
|
|
168
|
-
: linked.length === 1
|
|
191
|
+
: linked.length === 1 &&
|
|
192
|
+
!linked[0]?.projectedResultBindings.some(({ bindingId }) => bindingId === candidate.handleBindingId)
|
|
169
193
|
? "complete"
|
|
170
194
|
: linked.length > 1
|
|
171
195
|
? "partial"
|
|
@@ -208,31 +232,9 @@ const timerMethodFromBinding = (binding) => {
|
|
|
208
232
|
};
|
|
209
233
|
const timerNamespaceBinding = (binding) => binding?.directOrigins.some(({ specifier, importedPath }) => timerModule(specifier) && importedPath.length === 0) ?? false;
|
|
210
234
|
const timerModule = (specifier) => specifier === "timers" || specifier === "node:timers";
|
|
211
|
-
const assignedBindingId = (parent, node, state) => {
|
|
212
|
-
const identifier = t.isVariableDeclarator(parent) &&
|
|
213
|
-
parent.init === node &&
|
|
214
|
-
t.isIdentifier(parent.id)
|
|
215
|
-
? parent.id
|
|
216
|
-
: t.isAssignmentExpression(parent) &&
|
|
217
|
-
parent.right === node &&
|
|
218
|
-
t.isIdentifier(parent.left)
|
|
219
|
-
? parent.left
|
|
220
|
-
: null;
|
|
221
|
-
return identifier === null
|
|
222
|
-
? null
|
|
223
|
-
: (resolveSemanticBindingState(state, identifier, identifier.name)
|
|
224
|
-
?.bindingId ?? null);
|
|
225
|
-
};
|
|
226
235
|
const bindingId = (node, state) => t.isIdentifier(node)
|
|
227
236
|
? (resolveSemanticBindingState(state, node, node.name)?.bindingId ?? null)
|
|
228
237
|
: null;
|
|
229
|
-
const literalString = (node) => {
|
|
230
|
-
if (t.isStringLiteral(node))
|
|
231
|
-
return node.value;
|
|
232
|
-
if (t.isTemplateLiteral(node) && node.expressions.length === 0)
|
|
233
|
-
return node.quasis[0]?.value.cooked ?? node.quasis[0]?.value.raw ?? null;
|
|
234
|
-
return null;
|
|
235
|
-
};
|
|
236
238
|
const timerDelay = (candidate) => {
|
|
237
239
|
if (candidate.kind !== "schedule" || candidate.method === "setImmediate")
|
|
238
240
|
return null;
|
|
@@ -240,6 +242,3 @@ const timerDelay = (candidate) => {
|
|
|
240
242
|
return t.isNumericLiteral(delay) ? delay.value : null;
|
|
241
243
|
};
|
|
242
244
|
const timerId = (candidate) => `timer:${candidate.kind}:${String(candidate.node.start ?? -1)}:${String(candidate.node.end ?? -1)}`;
|
|
243
|
-
const memberCallee = (node) => t.isMemberExpression(node.callee) || t.isOptionalMemberExpression(node.callee)
|
|
244
|
-
? node.callee
|
|
245
|
-
: null;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as t from "@babel/types";
|
|
2
2
|
import { semanticCallableIdForNode, semanticReferenceRole, semanticStaticPropertyName, } from "./javascriptSemanticProjection.js";
|
|
3
|
-
import { resolveSemanticBindingState, } from "./javascriptSemanticState.js";
|
|
3
|
+
import { resolveSemanticBindingState, isUnshadowedGlobal, } from "./javascriptSemanticState.js";
|
|
4
4
|
import { parameterBindings, resolveLocalCallables, } from "./javascriptSemanticCallResolution.js";
|
|
5
5
|
import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
|
|
6
6
|
import { range } from "./javascriptStaticAnalysisHelpers.js";
|
|
7
|
+
import { assignedSemanticResultBindings } from "./javascriptSemanticDataEffectHelpers.js";
|
|
7
8
|
/** Recover direct-call and lexical-capture candidates from inert syntax. */
|
|
8
9
|
export const collectJavaScriptSemanticCalls = (program, state, callables) => {
|
|
9
10
|
const output = {
|
|
@@ -21,6 +22,7 @@ export const collectJavaScriptSemanticCalls = (program, state, callables) => {
|
|
|
21
22
|
output,
|
|
22
23
|
bindingResolutionCache: new Map(),
|
|
23
24
|
parameterBindingCache: new Map(),
|
|
25
|
+
ancestors: [],
|
|
24
26
|
};
|
|
25
27
|
const callableStack = [];
|
|
26
28
|
traverseJavaScriptAst(program, {
|
|
@@ -32,12 +34,15 @@ export const collectJavaScriptSemanticCalls = (program, state, callables) => {
|
|
|
32
34
|
const owner = enclosingFunction(callableStack);
|
|
33
35
|
collectCapture(node, parent, owner, context);
|
|
34
36
|
collectDynamicProperty(node, owner, state, output);
|
|
37
|
+
collectDynamicScope(node, owner, state, output);
|
|
35
38
|
if (t.isCallExpression(node) ||
|
|
36
39
|
t.isOptionalCallExpression(node) ||
|
|
37
40
|
t.isNewExpression(node))
|
|
38
41
|
collectCallSite(node, parent, owner, context);
|
|
42
|
+
context.ancestors.push(node);
|
|
39
43
|
},
|
|
40
44
|
exit: (node) => {
|
|
45
|
+
context.ancestors.pop();
|
|
41
46
|
const callableId = semanticCallableIdForNode(node);
|
|
42
47
|
if (callableId !== null &&
|
|
43
48
|
callableStack.at(-1)?.callableId === callableId)
|
|
@@ -79,7 +84,7 @@ const collectCallSite = (node, parent, owner, context) => {
|
|
|
79
84
|
arguments: argumentsValue,
|
|
80
85
|
};
|
|
81
86
|
output.callSites.push(site);
|
|
82
|
-
collectCallResultFlow(site, node,
|
|
87
|
+
collectCallResultFlow(site, node, context);
|
|
83
88
|
if (site.resolution !== "exact")
|
|
84
89
|
addFrontier({
|
|
85
90
|
kind: "dynamic-call",
|
|
@@ -91,31 +96,24 @@ const collectCallSite = (node, parent, owner, context) => {
|
|
|
91
96
|
if (site.kind === "call")
|
|
92
97
|
collectReturnFlows(site, callableById, state, output);
|
|
93
98
|
};
|
|
94
|
-
const collectCallResultFlow = (site, node,
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (binding === undefined || definition === undefined)
|
|
113
|
-
return;
|
|
114
|
-
context.output.callResultFlows.push({
|
|
115
|
-
callSiteId: site.callSiteId,
|
|
116
|
-
bindingId: binding.bindingId,
|
|
117
|
-
definitionLocation: definition.location,
|
|
118
|
-
});
|
|
99
|
+
const collectCallResultFlow = (site, node, context) => {
|
|
100
|
+
for (const assigned of assignedSemanticResultBindings(node, context.ancestors, context.state).filter(({ projectionPath }) => projectionPath.length === 0)) {
|
|
101
|
+
const binding = [...context.state.bindingsById.values()].find(({ bindingId }) => bindingId === assigned.bindingId);
|
|
102
|
+
if (binding === undefined)
|
|
103
|
+
continue;
|
|
104
|
+
const identifierRange = range(assigned.identifier);
|
|
105
|
+
const definition = binding.definitions.find(({ location }) => location.start.line === identifierRange.start.line &&
|
|
106
|
+
location.start.column === identifierRange.start.column &&
|
|
107
|
+
location.end.line === identifierRange.end.line &&
|
|
108
|
+
location.end.column === identifierRange.end.column);
|
|
109
|
+
if (definition === undefined)
|
|
110
|
+
continue;
|
|
111
|
+
context.output.callResultFlows.push({
|
|
112
|
+
callSiteId: site.callSiteId,
|
|
113
|
+
bindingId: binding.bindingId,
|
|
114
|
+
definitionLocation: definition.location,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
119
117
|
};
|
|
120
118
|
const retainedArguments = (nodes) => {
|
|
121
119
|
const retained = [];
|
|
@@ -223,6 +221,27 @@ const collectDynamicProperty = (node, owner, state, output) => {
|
|
|
223
221
|
reason: "Computed object property is not a static string or number.",
|
|
224
222
|
}, state, output);
|
|
225
223
|
};
|
|
224
|
+
/**
|
|
225
|
+
* `with (o) { … }` and `eval("…")` decide at runtime which bindings exist, so
|
|
226
|
+
* every name inside them is unresolvable statically. Recording the frontier
|
|
227
|
+
* is what keeps the analyzer from presenting an empty or partial resolution as
|
|
228
|
+
* an observed fact — silence here would read as "nothing to resolve".
|
|
229
|
+
*/
|
|
230
|
+
const collectDynamicScope = (node, owner, state, output) => {
|
|
231
|
+
const reason = t.isWithStatement(node)
|
|
232
|
+
? "`with` introduces a runtime binding environment; names inside are not statically resolvable."
|
|
233
|
+
: t.isCallExpression(node) && isUnshadowedGlobal(node.callee, state, "eval")
|
|
234
|
+
? "`eval` can declare bindings at runtime; names inside the evaluated source are not statically resolvable."
|
|
235
|
+
: null;
|
|
236
|
+
if (reason === null)
|
|
237
|
+
return;
|
|
238
|
+
addFrontier({
|
|
239
|
+
kind: "dynamic-scope",
|
|
240
|
+
callableId: owner?.callableId ?? null,
|
|
241
|
+
location: range(node),
|
|
242
|
+
reason,
|
|
243
|
+
}, state, output);
|
|
244
|
+
};
|
|
226
245
|
const addFrontier = (frontier, state, output) => {
|
|
227
246
|
output.frontiers.push(frontier);
|
|
228
247
|
};
|
|
@@ -2,7 +2,8 @@ import * as t from "@babel/types";
|
|
|
2
2
|
import { semanticCallableIdForNode, semanticStaticPropertyName, } from "./javascriptSemanticProjection.js";
|
|
3
3
|
import { resolveSemanticBindingState, } from "./javascriptSemanticState.js";
|
|
4
4
|
import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
|
|
5
|
-
import { compareCodePoints,
|
|
5
|
+
import { compareCodePoints, range } from "./javascriptStaticAnalysisHelpers.js";
|
|
6
|
+
import { dataEffectLiteralString, dataEffectMemberCallee, assignedSemanticResultBindings, scalarAssignedResultBinding, semanticProjectedBindingFacts, } from "./javascriptSemanticDataEffectHelpers.js";
|
|
6
7
|
const CHILD_PROCESS_METHODS = ["spawn", "exec", "execFile", "fork"];
|
|
7
8
|
const CHILD_LISTENER_METHODS = ["on", "once", "addListener"];
|
|
8
9
|
/** Recover explicit asynchronous node:child_process ownership candidates. */
|
|
@@ -18,36 +19,44 @@ const collectSpawns = (program, state, callables) => {
|
|
|
18
19
|
const output = [];
|
|
19
20
|
const admittedCallables = new Set(callables.map(({ callableId }) => callableId));
|
|
20
21
|
const callableStack = [];
|
|
22
|
+
const ancestors = [];
|
|
21
23
|
traverseJavaScriptAst(program, {
|
|
22
|
-
enter: (node
|
|
24
|
+
enter: (node) => {
|
|
23
25
|
const callableId = semanticCallableIdForNode(node);
|
|
24
26
|
if (callableId !== null && admittedCallables.has(callableId))
|
|
25
27
|
callableStack.push(callableId);
|
|
26
|
-
if (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
if (t.isCallExpression(node) || t.isOptionalCallExpression(node)) {
|
|
29
|
+
const method = childProcessMethod(node.callee, state);
|
|
30
|
+
if (method !== null) {
|
|
31
|
+
const projectedResultBindings = assignedSemanticResultBindings(node, ancestors, state);
|
|
32
|
+
output.push({
|
|
33
|
+
node,
|
|
34
|
+
method,
|
|
35
|
+
ownerCallableId: callableStack.at(-1) ?? null,
|
|
36
|
+
resultBindingId: scalarAssignedResultBinding(projectedResultBindings),
|
|
37
|
+
projectedResultBindings: semanticProjectedBindingFacts(projectedResultBindings.filter(({ projectionPath }) => projectionPath.length > 0)),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
ancestors.push(node);
|
|
42
|
+
},
|
|
43
|
+
exit: (node) => {
|
|
44
|
+
ancestors.pop();
|
|
45
|
+
popCallable(node, callableStack);
|
|
37
46
|
},
|
|
38
|
-
exit: (node) => popCallable(node, callableStack),
|
|
39
47
|
});
|
|
40
48
|
return output;
|
|
41
49
|
};
|
|
42
50
|
const immutableSpawn = (candidate) => {
|
|
43
51
|
const options = spawnOptions(candidate);
|
|
44
|
-
const command =
|
|
52
|
+
const command = dataEffectLiteralString(candidate.node.arguments[0]);
|
|
45
53
|
return {
|
|
46
54
|
processId: spawnId(candidate),
|
|
47
55
|
method: candidate.method,
|
|
48
56
|
location: range(candidate.node),
|
|
49
57
|
ownerCallableId: candidate.ownerCallableId,
|
|
50
58
|
resultBindingId: candidate.resultBindingId,
|
|
59
|
+
projectedResultBindings: candidate.projectedResultBindings,
|
|
51
60
|
command,
|
|
52
61
|
argvCount: spawnArgvCount(candidate),
|
|
53
62
|
environmentSupplied: objectHasProperty(options, "env"),
|
|
@@ -63,11 +72,15 @@ const collectInteractions = (program, state, callables, spawns) => {
|
|
|
63
72
|
const spawnsByBinding = new Map();
|
|
64
73
|
for (const spawn of spawns) {
|
|
65
74
|
spawnByNode.set(spawn.node, spawn);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
75
|
+
const ids = [
|
|
76
|
+
...(spawn.resultBindingId === null ? [] : [spawn.resultBindingId]),
|
|
77
|
+
...spawn.projectedResultBindings.map(({ bindingId }) => bindingId),
|
|
78
|
+
];
|
|
79
|
+
for (const id of ids) {
|
|
80
|
+
const existing = spawnsByBinding.get(id) ?? [];
|
|
81
|
+
existing.push(spawn);
|
|
82
|
+
spawnsByBinding.set(id, existing);
|
|
83
|
+
}
|
|
71
84
|
}
|
|
72
85
|
const context = {
|
|
73
86
|
state,
|
|
@@ -92,7 +105,7 @@ const collectInteractions = (program, state, callables, spawns) => {
|
|
|
92
105
|
};
|
|
93
106
|
const childInteraction = (node, ownerCallableId, context) => {
|
|
94
107
|
const { state, spawnByNode, spawnsByBinding } = context;
|
|
95
|
-
const member =
|
|
108
|
+
const member = dataEffectMemberCallee(node);
|
|
96
109
|
if (member === null)
|
|
97
110
|
return null;
|
|
98
111
|
const method = semanticStaticPropertyName(member.property, member.computed);
|
|
@@ -117,17 +130,20 @@ const childInteraction = (node, ownerCallableId, context) => {
|
|
|
117
130
|
.sort(compareCodePoints),
|
|
118
131
|
eventName: kind === "listener" ? eventName : null,
|
|
119
132
|
signalName: kind === "signal"
|
|
120
|
-
? (
|
|
133
|
+
? (dataEffectLiteralString(node.arguments[0]) ?? "SIGTERM")
|
|
121
134
|
: null,
|
|
122
135
|
listenerLocation: kind === "listener" && t.isNode(listener) ? range(listener) : null,
|
|
123
|
-
resolution: linked.length === 1
|
|
136
|
+
resolution: linked.length === 1 &&
|
|
137
|
+
!linked[0]?.projectedResultBindings.some(({ bindingId }) => bindingId === binding?.bindingId)
|
|
138
|
+
? "complete"
|
|
139
|
+
: "partial",
|
|
124
140
|
};
|
|
125
141
|
};
|
|
126
142
|
const classifyInteraction = (method, argument) => {
|
|
127
143
|
if (method === "kill")
|
|
128
144
|
return { kind: "signal", interactionMethod: "kill", eventName: null };
|
|
129
145
|
const listenerMethod = CHILD_LISTENER_METHODS.find((candidate) => candidate === method);
|
|
130
|
-
const eventName =
|
|
146
|
+
const eventName = dataEffectLiteralString(argument);
|
|
131
147
|
return listenerMethod !== undefined &&
|
|
132
148
|
(eventName === "exit" || eventName === "error")
|
|
133
149
|
? { kind: "listener", interactionMethod: listenerMethod, eventName }
|
|
@@ -190,38 +206,15 @@ const stdioMode = (options) => {
|
|
|
190
206
|
return "dynamic";
|
|
191
207
|
};
|
|
192
208
|
const objectProperty = (object, name) => object?.properties.find((property) => (t.isObjectMethod(property) || t.isObjectProperty(property)) &&
|
|
193
|
-
|
|
209
|
+
// `{[env]: vars}` has a dynamic key; treating it as `env` would claim
|
|
210
|
+
// the caller supplied an environment when the real key is unknown.
|
|
211
|
+
semanticStaticPropertyName(property.key, property.computed) === name) ?? null;
|
|
194
212
|
const objectBinding = (node, state) => t.isIdentifier(node)
|
|
195
213
|
? resolveSemanticBindingState(state, node, node.name)
|
|
196
214
|
: undefined;
|
|
197
|
-
const assignedBindingId = (parent, node, state) => {
|
|
198
|
-
const identifier = t.isVariableDeclarator(parent) &&
|
|
199
|
-
parent.init === node &&
|
|
200
|
-
t.isIdentifier(parent.id)
|
|
201
|
-
? parent.id
|
|
202
|
-
: t.isAssignmentExpression(parent) &&
|
|
203
|
-
parent.right === node &&
|
|
204
|
-
t.isIdentifier(parent.left)
|
|
205
|
-
? parent.left
|
|
206
|
-
: null;
|
|
207
|
-
return identifier === null
|
|
208
|
-
? null
|
|
209
|
-
: (resolveSemanticBindingState(state, identifier, identifier.name)
|
|
210
|
-
?.bindingId ?? null);
|
|
211
|
-
};
|
|
212
|
-
const literalString = (node) => {
|
|
213
|
-
if (t.isStringLiteral(node))
|
|
214
|
-
return node.value;
|
|
215
|
-
if (t.isTemplateLiteral(node) && node.expressions.length === 0)
|
|
216
|
-
return node.quasis[0]?.value.cooked ?? node.quasis[0]?.value.raw ?? null;
|
|
217
|
-
return null;
|
|
218
|
-
};
|
|
219
215
|
const popCallable = (node, stack) => {
|
|
220
216
|
const callableId = semanticCallableIdForNode(node);
|
|
221
217
|
if (callableId !== null && stack.at(-1) === callableId)
|
|
222
218
|
stack.pop();
|
|
223
219
|
};
|
|
224
220
|
const spawnId = (candidate) => `child:spawn:${String(candidate.node.start ?? -1)}:${String(candidate.node.end ?? -1)}`;
|
|
225
|
-
const memberCallee = (node) => t.isMemberExpression(node.callee) || t.isOptionalMemberExpression(node.callee)
|
|
226
|
-
? node.callee
|
|
227
|
-
: null;
|
|
@@ -1,7 +1,96 @@
|
|
|
1
1
|
import * as t from "@babel/types";
|
|
2
|
-
import { semanticCallableIdForNode
|
|
2
|
+
import { semanticCallableIdForNode } from "./javascriptSemanticProjection.js";
|
|
3
3
|
import { resolveSemanticBindingState, semanticResolutionBlocked, } from "./javascriptSemanticState.js";
|
|
4
4
|
import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
|
|
5
|
+
import { semanticStaticPropertyName } from "./javascriptAstValues.js";
|
|
6
|
+
/** Resolve bindings written by the nearest variable or assignment owner. */
|
|
7
|
+
export const assignedSemanticResultBindings = (node, ancestors, state) => {
|
|
8
|
+
for (let index = ancestors.length - 1; index >= 0; index -= 1) {
|
|
9
|
+
const owner = ancestors[index];
|
|
10
|
+
if (owner === undefined)
|
|
11
|
+
continue;
|
|
12
|
+
let pattern;
|
|
13
|
+
let source = null;
|
|
14
|
+
if (t.isVariableDeclarator(owner)) {
|
|
15
|
+
pattern = owner.id;
|
|
16
|
+
source = owner.init ?? null;
|
|
17
|
+
}
|
|
18
|
+
else if (t.isAssignmentExpression(owner)) {
|
|
19
|
+
pattern = owner.left;
|
|
20
|
+
source = owner.right;
|
|
21
|
+
}
|
|
22
|
+
if (pattern !== undefined &&
|
|
23
|
+
source !== null &&
|
|
24
|
+
assignedSourceIs(node, source))
|
|
25
|
+
return projectedPatternBindings(pattern, state);
|
|
26
|
+
if (semanticCallableIdForNode(owner) !== null)
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
return [];
|
|
30
|
+
};
|
|
31
|
+
const assignedSourceIs = (node, source) => {
|
|
32
|
+
let value = source;
|
|
33
|
+
while (true) {
|
|
34
|
+
if (t.isAwaitExpression(value))
|
|
35
|
+
value = value.argument;
|
|
36
|
+
else if (t.isParenthesizedExpression(value) ||
|
|
37
|
+
t.isTSAsExpression(value) ||
|
|
38
|
+
t.isTSTypeAssertion(value) ||
|
|
39
|
+
t.isTypeCastExpression(value) ||
|
|
40
|
+
t.isTSSatisfiesExpression(value))
|
|
41
|
+
value = value.expression;
|
|
42
|
+
else
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
return value === node;
|
|
46
|
+
};
|
|
47
|
+
const projectedPatternBindings = (pattern, state) => {
|
|
48
|
+
const output = [];
|
|
49
|
+
const visit = (current, path, partial) => {
|
|
50
|
+
if (t.isIdentifier(current)) {
|
|
51
|
+
const binding = resolveSemanticBindingState(state, current, current.name);
|
|
52
|
+
if (binding !== undefined)
|
|
53
|
+
output.push({
|
|
54
|
+
bindingId: binding.bindingId,
|
|
55
|
+
identifier: current,
|
|
56
|
+
projectionPath: path,
|
|
57
|
+
resolution: partial ? "partial" : "complete",
|
|
58
|
+
});
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (t.isAssignmentPattern(current))
|
|
62
|
+
return visit(current.left, path, true);
|
|
63
|
+
if (t.isRestElement(current))
|
|
64
|
+
return visit(current.argument, [...path, null], true);
|
|
65
|
+
if (t.isObjectPattern(current)) {
|
|
66
|
+
for (const property of current.properties) {
|
|
67
|
+
if (t.isRestElement(property))
|
|
68
|
+
visit(property.argument, [...path, null], true);
|
|
69
|
+
else
|
|
70
|
+
visit(property.value, [
|
|
71
|
+
...path,
|
|
72
|
+
semanticStaticPropertyName(property.key, property.computed) ||
|
|
73
|
+
null,
|
|
74
|
+
], partial ||
|
|
75
|
+
semanticStaticPropertyName(property.key, property.computed) ===
|
|
76
|
+
"");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (t.isArrayPattern(current)) {
|
|
80
|
+
current.elements.forEach((element, index) => {
|
|
81
|
+
if (element !== null)
|
|
82
|
+
visit(element, [...path, index], partial);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
visit(pattern, [], false);
|
|
87
|
+
return output;
|
|
88
|
+
};
|
|
89
|
+
export const semanticProjectedBindingFacts = (bindings) => bindings.map(({ identifier: _identifier, ...fact }) => fact);
|
|
90
|
+
/** Return a scalar owner only for an unprojected identifier result. */
|
|
91
|
+
export const scalarAssignedResultBinding = (bindings) => bindings.length === 1 && bindings[0]?.projectionPath.length === 0
|
|
92
|
+
? (bindings[0]?.bindingId ?? null)
|
|
93
|
+
: null;
|
|
5
94
|
/** Resolve a direct or namespace-imported built-in method. */
|
|
6
95
|
export const builtinDataEffectMethod = (callee, state, specifiers) => {
|
|
7
96
|
if (t.isIdentifier(callee)) {
|
|
@@ -38,23 +127,7 @@ export const isSemanticProcessObject = (node, state) => {
|
|
|
38
127
|
};
|
|
39
128
|
/** Resolve the nearest direct variable/assignment owner before a callable. */
|
|
40
129
|
export const outerDataEffectBinding = (node, context) => {
|
|
41
|
-
|
|
42
|
-
const ancestor = context.ancestors[index];
|
|
43
|
-
if (ancestor === undefined)
|
|
44
|
-
continue;
|
|
45
|
-
if (t.isVariableDeclarator(ancestor) &&
|
|
46
|
-
t.isNode(ancestor.init) &&
|
|
47
|
-
containsSemanticNode(ancestor.init, node) &&
|
|
48
|
-
t.isIdentifier(ancestor.id))
|
|
49
|
-
return (resolveSemanticBindingState(context.state, ancestor.id, ancestor.id.name)?.bindingId ?? null);
|
|
50
|
-
if (t.isAssignmentExpression(ancestor) &&
|
|
51
|
-
containsSemanticNode(ancestor.right, node) &&
|
|
52
|
-
t.isIdentifier(ancestor.left))
|
|
53
|
-
return (resolveSemanticBindingState(context.state, ancestor.left, ancestor.left.name)?.bindingId ?? null);
|
|
54
|
-
if (semanticCallableIdForNode(ancestor) !== null)
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
return null;
|
|
130
|
+
return scalarAssignedResultBinding(assignedSemanticResultBindings(node, context.ancestors, context.state));
|
|
58
131
|
};
|
|
59
132
|
/** Traverse with exact callable and ancestor stacks. */
|
|
60
133
|
export const traverseDataEffects = (program, context, visit) => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as t from "@babel/types";
|
|
2
2
|
import { semanticStaticPropertyName } from "./javascriptSemanticProjection.js";
|
|
3
3
|
import { resolveSemanticBindingState, semanticResolutionBlocked, } from "./javascriptSemanticState.js";
|
|
4
|
-
import { builtinDataEffectMethod as builtinMethod, containsSemanticNode as containsNode, dataEffectArgumentBindingId as argumentBindingId, dataEffectLiteralString as literalString, dataEffectMemberCallee as memberCallee, dataEffectMemberObject as memberObject, dataEffectPrimitive as primitiveValue, isSemanticProcessObject as isProcessObject, outerDataEffectBinding as outerAssignedBinding, traverseDataEffects as traverseWithContext, } from "./javascriptSemanticDataEffectHelpers.js";
|
|
5
|
-
import { compareCodePoints,
|
|
4
|
+
import { builtinDataEffectMethod as builtinMethod, containsSemanticNode as containsNode, dataEffectArgumentBindingId as argumentBindingId, dataEffectLiteralString as literalString, dataEffectMemberCallee as memberCallee, dataEffectMemberObject as memberObject, dataEffectPrimitive as primitiveValue, isSemanticProcessObject as isProcessObject, outerDataEffectBinding as outerAssignedBinding, assignedSemanticResultBindings, semanticProjectedBindingFacts, traverseDataEffects as traverseWithContext, } from "./javascriptSemanticDataEffectHelpers.js";
|
|
5
|
+
import { compareCodePoints, range } from "./javascriptStaticAnalysisHelpers.js";
|
|
6
6
|
/** Recover configuration, request, and boundary candidates from inert syntax. */
|
|
7
7
|
export const collectJavaScriptSemanticDataEffects = (program, state, callables) => {
|
|
8
8
|
const context = {
|
|
@@ -126,6 +126,7 @@ const collectRequests = (program, context) => {
|
|
|
126
126
|
location: range(node),
|
|
127
127
|
ownerCallableId: context.callableStack.at(-1) ?? null,
|
|
128
128
|
resultBindingId: outerAssignedBinding(node, context),
|
|
129
|
+
projectedResultBindings: semanticProjectedBindingFacts(assignedSemanticResultBindings(node, context.ancestors, context.state).filter(({ projectionPath }) => projectionPath.length > 0)),
|
|
129
130
|
linkedRequestIds: [],
|
|
130
131
|
endpoint,
|
|
131
132
|
fields: requestFields(node, method, context.state),
|
|
@@ -138,12 +139,17 @@ const collectRequests = (program, context) => {
|
|
|
138
139
|
const collectResponseConsumers = (program, context, requests) => {
|
|
139
140
|
const requestsByBinding = new Map();
|
|
140
141
|
for (const request of requests) {
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
142
|
+
const bindingIds = [
|
|
143
|
+
...(request.operation.resultBindingId === null
|
|
144
|
+
? []
|
|
145
|
+
: [request.operation.resultBindingId]),
|
|
146
|
+
...request.operation.projectedResultBindings.map(({ bindingId }) => bindingId),
|
|
147
|
+
];
|
|
148
|
+
for (const bindingId of bindingIds) {
|
|
149
|
+
const existing = requestsByBinding.get(bindingId) ?? [];
|
|
150
|
+
existing.push(request);
|
|
151
|
+
requestsByBinding.set(bindingId, existing);
|
|
152
|
+
}
|
|
147
153
|
}
|
|
148
154
|
const output = [];
|
|
149
155
|
traverseWithContext(program, context, (node) => {
|
|
@@ -168,12 +174,16 @@ const collectResponseConsumers = (program, context, requests) => {
|
|
|
168
174
|
location: range(node),
|
|
169
175
|
ownerCallableId: context.callableStack.at(-1) ?? null,
|
|
170
176
|
resultBindingId: outerAssignedBinding(node, context),
|
|
177
|
+
projectedResultBindings: semanticProjectedBindingFacts(assignedSemanticResultBindings(node, context.ancestors, context.state).filter(({ projectionPath }) => projectionPath.length > 0)),
|
|
171
178
|
linkedRequestIds: linked
|
|
172
179
|
.map(({ operation }) => operation.requestId)
|
|
173
180
|
.sort(compareCodePoints),
|
|
174
181
|
endpoint: null,
|
|
175
182
|
fields: [],
|
|
176
|
-
resolution: linked.length === 1
|
|
183
|
+
resolution: linked.length === 1 &&
|
|
184
|
+
!linked[0]?.operation.projectedResultBindings.some(({ bindingId }) => bindingId === binding?.bindingId)
|
|
185
|
+
? "complete"
|
|
186
|
+
: "partial",
|
|
177
187
|
});
|
|
178
188
|
});
|
|
179
189
|
return output;
|
|
@@ -256,7 +266,9 @@ const requestFields = (node, method, state) => {
|
|
|
256
266
|
return candidate.properties.flatMap((property) => {
|
|
257
267
|
if (!t.isObjectProperty(property))
|
|
258
268
|
return [];
|
|
259
|
-
|
|
269
|
+
// `{[key]: 1}` sends no knowable field name; reporting `key` would invent
|
|
270
|
+
// a request field that may not exist.
|
|
271
|
+
const name = semanticStaticPropertyName(property.key, property.computed);
|
|
260
272
|
if (name.length === 0)
|
|
261
273
|
return [];
|
|
262
274
|
return [
|