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.
Files changed (434) hide show
  1. package/README.md +183 -332
  2. package/bridge/ghidra/ReaGhidraBridge.java +561 -74
  3. package/bridge/hopper_bridge.py +70 -27
  4. package/bridge/native/ReaNativeUI.swift +157 -0
  5. package/dist/application/AnalysisContextQueries.js +19 -5
  6. package/dist/application/AnalysisSnapshotCache.js +30 -11
  7. package/dist/application/AppleAssetCatalogAnalysis.js +171 -0
  8. package/dist/application/ArtifactExtractionDestination.js +0 -12
  9. package/dist/application/ArtifactGraphConstruction.js +44 -11
  10. package/dist/application/ArtifactInventory/classify.js +7 -15
  11. package/dist/application/ArtifactInventory/hash.js +4 -2
  12. package/dist/application/ArtifactInventory/policy.js +2 -17
  13. package/dist/application/ArtifactInventory/reader.js +3 -3
  14. package/dist/application/ArtifactInventory/scanCanonical.js +2 -2
  15. package/dist/application/ArtifactInventory/scanReader.js +12 -4
  16. package/dist/application/ArtifactInventory/types.js +0 -3
  17. package/dist/application/BinarySession.js +28 -43
  18. package/dist/application/BinarySessionExecution.js +37 -1
  19. package/dist/application/BinaryTargetResolver.js +50 -4
  20. package/dist/application/BrowserEvidence.js +36 -7
  21. package/dist/application/BrowserObservationService.js +17 -44
  22. package/dist/application/BrowserScenarioCaptureService.js +2 -35
  23. package/dist/application/BrowserScenarioEvidence.js +13 -9
  24. package/dist/application/CapabilityClientRequirements.js +2 -11
  25. package/dist/application/CapabilityInventory.js +21 -35
  26. package/dist/application/ClientConfigurationDocument.js +84 -7
  27. package/dist/application/ClientRegistrationIdentity.js +32 -0
  28. package/dist/application/ClientRegistrationStatus.js +59 -6
  29. package/dist/application/DirectAnalysis.js +37 -58
  30. package/dist/application/DirectAnalysisStatus.js +4 -4
  31. package/dist/application/Doctor.js +89 -80
  32. package/dist/application/DoctorDiagnostics.js +2 -26
  33. package/dist/application/DoctorScope.js +8 -14
  34. package/dist/application/ElectronActiveEvidence.js +10 -27
  35. package/dist/application/ElectronActiveObservationService.js +9 -36
  36. package/dist/application/ElectronBoundaryAnalysis.js +2 -0
  37. package/dist/application/ElectronBoundaryGraphNative.js +1 -1
  38. package/dist/application/ElectronEvidence.js +8 -3
  39. package/dist/application/ElectronObservationService.js +9 -25
  40. package/dist/application/EnhancedLiteralTracing.js +4 -8
  41. package/dist/application/EnhancedTools.js +15 -35
  42. package/dist/application/FilesystemSnapshot.js +7 -8
  43. package/dist/application/JavaScriptApplicationEvidenceGraph.js +2 -1
  44. package/dist/application/JavaScriptApplicationWorkflowService.js +31 -7
  45. package/dist/application/JavaScriptArtifactAnalysis.js +6 -4
  46. package/dist/application/JavaScriptArtifactFiles.js +5 -0
  47. package/dist/application/JavaScriptArtifactPathResolution.js +179 -47
  48. package/dist/application/JavaScriptRuntimeObservationEvidence.js +6 -3
  49. package/dist/application/JavaScriptRuntimeObservationService.js +9 -25
  50. package/dist/application/JavaScriptRuntimeReconciliationService.js +45 -4
  51. package/dist/application/JavaScriptSemanticGraphAsyncProjection.js +11 -0
  52. package/dist/application/JavaScriptSemanticGraphChildProcessProjection.js +11 -0
  53. package/dist/application/JavaScriptSemanticGraphDataProjection.js +11 -0
  54. package/dist/application/JavaScriptSemanticGraphFlowProjection.js +14 -5
  55. package/dist/application/JsonFiles.js +1 -1
  56. package/dist/application/LazyAnalysisProvider.js +27 -6
  57. package/dist/application/ManagedMemberComparisonService.js +19 -6
  58. package/dist/application/NativeApiInspection.js +2 -0
  59. package/dist/application/NativeCallRoutes.js +72 -0
  60. package/dist/application/NativeDispatchMetadataInspection.js +33 -0
  61. package/dist/application/NativeUiActionTrace.js +73 -49
  62. package/dist/application/NativeValueTrace.js +320 -0
  63. package/dist/application/ProcessCaptureCapability.js +32 -5
  64. package/dist/application/ProcessCaptureEnvironment.js +9 -26
  65. package/dist/application/ProcessCaptureError.js +1 -5
  66. package/dist/application/ProcessCaptureJournal.js +3 -40
  67. package/dist/application/ProcessCaptureLifecycle.js +102 -111
  68. package/dist/application/ProcessCli.js +18 -25
  69. package/dist/application/ProcessEvidence.js +5 -7
  70. package/dist/application/ProcessFilesystemEffects.js +36 -0
  71. package/dist/application/ProcessHarness.js +41 -120
  72. package/dist/application/ProcessNormalization.js +2 -17
  73. package/dist/application/ProcessScenarioRuntimeValidation.js +76 -0
  74. package/dist/application/ReferenceSourceImport.js +3 -4
  75. package/dist/application/Setup.js +236 -84
  76. package/dist/application/SetupClientConfiguration.js +14 -9
  77. package/dist/application/SetupPlan.js +138 -86
  78. package/dist/application/SetupSkill.js +0 -1
  79. package/dist/application/SupportedClients.js +102 -21
  80. package/dist/application/Uninstall.js +31 -20
  81. package/dist/application/Update.js +93 -0
  82. package/dist/application/UpdateMaintenance.js +108 -0
  83. package/dist/application/UpdateRuntime.js +126 -0
  84. package/dist/application/runtime.js +13 -2
  85. package/dist/artifacts/ArtifactPaths.js +6 -8
  86. package/dist/artifacts/ArtifactProvider.js +94 -41
  87. package/dist/artifacts/AsarArtifactReader.js +19 -4
  88. package/dist/artifacts/KeyedArchiveReader.js +110 -0
  89. package/dist/artifacts/MachOSliceArtifactReader.js +53 -5
  90. package/dist/artifacts/ZipArtifactReader.js +18 -1
  91. package/dist/browser/BrowserScenarioSecrets.js +28 -1
  92. package/dist/browser/CdpBrowserProvider.js +36 -15
  93. package/dist/browser/CdpCaptureDocuments.js +22 -8
  94. package/dist/browser/CdpCaptureEventHandlers.js +14 -5
  95. package/dist/browser/CdpCaptureEventHelpers.js +13 -0
  96. package/dist/browser/CdpCaptureEvents.js +10 -1
  97. package/dist/browser/CdpElectronInspection.js +5 -10
  98. package/dist/browser/CdpElectronProvider.js +1 -5
  99. package/dist/browser/CdpElectronScripts.js +1 -1
  100. package/dist/browser/CdpEndpoint.js +3 -2
  101. package/dist/browser/CdpObservationSession.js +14 -10
  102. package/dist/browser/CdpPageCapture.js +1 -1
  103. package/dist/browser/CdpPageCaptureScripts.js +1 -1
  104. package/dist/browser/CdpSafeMetadata.js +5 -4
  105. package/dist/browser/CdpScreenshot.js +16 -5
  106. package/dist/browser/CdpTargetSession.js +25 -4
  107. package/dist/browser/CdpWebMcpDiscovery.js +93 -20
  108. package/dist/browser/JavaScriptRuntimeScope.js +28 -2
  109. package/dist/browser/PlaywrightBrowserScenarioProvider.js +9 -8
  110. package/dist/browser/PlaywrightElectronActiveActions.js +3 -10
  111. package/dist/browser/PlaywrightElectronActiveProvider.js +5 -5
  112. package/dist/browser/PlaywrightScenarioActions.js +1 -1
  113. package/dist/browser/PlaywrightScenarioArtifacts.js +13 -25
  114. package/dist/browser/PlaywrightScenarioBrowser.js +28 -25
  115. package/dist/browser/PlaywrightScenarioEvents.js +82 -93
  116. package/dist/browser/PlaywrightScenarioSession.js +27 -123
  117. package/dist/browser/PngVisualDiff.js +22 -3
  118. package/dist/browser/V8InspectorCaptureProjection.js +7 -1
  119. package/dist/browser/V8InspectorProvider.js +60 -7
  120. package/dist/browser/WebSourceMapFetcher.js +99 -53
  121. package/dist/cli/artifactCommands.js +56 -12
  122. package/dist/cli/coreAnalysisCommands.js +110 -0
  123. package/dist/cli/managedCommands.js +1 -31
  124. package/dist/cli/setupCommands.js +16 -14
  125. package/dist/cli/utilityCommands.js +61 -4
  126. package/dist/cli.js +5 -7
  127. package/dist/cliApplicationCommands.js +0 -83
  128. package/dist/cliBrowserAdvancedCommands.js +7 -11
  129. package/dist/cliBrowserCommands.js +15 -23
  130. package/dist/cliBrowserContext.js +3 -24
  131. package/dist/cliBrowserScenarioCommands.js +2 -10
  132. package/dist/cliCommandNames.js +82 -7
  133. package/dist/cliElectronCommands.js +10 -36
  134. package/dist/cliJavaScriptRuntimeCommands.js +6 -30
  135. package/dist/cliJsonInput.js +4 -2
  136. package/dist/cliLogging.js +16 -7
  137. package/dist/cliObservationOptions.js +1 -1
  138. package/dist/cliOutput.js +2 -4
  139. package/dist/cliProcessCommands.js +6 -33
  140. package/dist/cliSetup.js +90 -160
  141. package/dist/config/environment.js +2 -78
  142. package/dist/config/parseConfig.js +18 -109
  143. package/dist/config/parsers.js +0 -23
  144. package/dist/contracts/applicationToolContracts.js +1 -118
  145. package/dist/contracts/artifactToolContracts.js +11 -19
  146. package/dist/contracts/browserScenarioToolContracts.js +1 -5
  147. package/dist/contracts/browserToolContracts.js +9 -16
  148. package/dist/contracts/electronToolContracts.js +5 -6
  149. package/dist/contracts/enhancedInputs.js +3 -2
  150. package/dist/contracts/errorSchemas.js +16 -40
  151. package/dist/contracts/functionWorkflowToolContracts.js +2 -2
  152. package/dist/contracts/javascriptApplicationWorkflowExamples.js +2 -2
  153. package/dist/contracts/javascriptRuntimeObservationToolContracts.js +4 -4
  154. package/dist/contracts/javascriptRuntimeReconciliationExample.js +1 -1
  155. package/dist/contracts/managedToolContracts.js +7 -4
  156. package/dist/contracts/managedWorkflowExamples.js +0 -22
  157. package/dist/contracts/managedWorkflowToolContracts.js +16 -31
  158. package/dist/contracts/nativeToolContracts.js +9 -0
  159. package/dist/contracts/promptContracts.js +6 -6
  160. package/dist/contracts/sessionToolSchemas.js +3 -3
  161. package/dist/contracts/toolContractExamples.js +4 -3
  162. package/dist/contracts/toolContracts.js +18 -7
  163. package/dist/contracts/toolEffects.js +34 -21
  164. package/dist/contracts/toolOutputSchemaGroups.js +18 -5
  165. package/dist/contracts/toolOutputSchemaPrimitives.js +9 -6
  166. package/dist/contracts/toolSchemaMetadata.js +5 -8
  167. package/dist/doctorRuntime.js +0 -41
  168. package/dist/domain/analysisErrorPresentation.js +4 -28
  169. package/dist/domain/analysisErrorProjection.js +33 -50
  170. package/dist/domain/analysisProfile.js +1 -1
  171. package/dist/domain/analysisSnapshot.js +77 -3
  172. package/dist/domain/androidApplication.js +5 -4
  173. package/dist/domain/appleApplication.js +5 -4
  174. package/dist/domain/appleAssetCatalog.js +127 -0
  175. package/dist/domain/artifactComparison.js +7 -11
  176. package/dist/domain/artifactGraph.js +8 -6
  177. package/dist/domain/artifactInspection.js +13 -12
  178. package/dist/domain/binaryTarget.js +23 -9
  179. package/dist/domain/browserObservation.js +43 -24
  180. package/dist/domain/browserObservationSchemas.js +2 -1
  181. package/dist/domain/browserScenario.js +7 -107
  182. package/dist/domain/browserScenarioCapture.js +0 -1
  183. package/dist/domain/browserScenarioCaptureValues.js +5 -4
  184. package/dist/domain/browserScenarioDiff.js +1 -3
  185. package/dist/domain/browserScenarioValues.js +16 -107
  186. package/dist/domain/bundleComparison.js +18 -17
  187. package/dist/domain/callPathSchemas.js +17 -7
  188. package/dist/domain/changedBehavior.js +2 -3
  189. package/dist/domain/comparisonSemantics.js +19 -0
  190. package/dist/domain/completionLedgerGeneration.js +3 -2
  191. package/dist/domain/conformancePackage.js +2 -1
  192. package/dist/domain/conformanceTrustGate.js +3 -5
  193. package/dist/domain/customProtocolCapture.js +2 -2
  194. package/dist/domain/digests.js +30 -0
  195. package/dist/domain/dosMz.js +83 -0
  196. package/dist/domain/electronActiveObservation.js +7 -5
  197. package/dist/domain/electronObservation.js +3 -2
  198. package/dist/domain/electronStaticAnalysisNative.js +15 -6
  199. package/dist/domain/emptyArraySchema.js +3 -0
  200. package/dist/domain/errors.js +10 -28
  201. package/dist/domain/evidence.js +5 -3
  202. package/dist/domain/evidenceCompletionLedger.js +3 -2
  203. package/dist/domain/functionComparisonNormalization.js +24 -18
  204. package/dist/domain/functionComparisonResults.js +3 -7
  205. package/dist/domain/functionComparisonSchemas.js +3 -2
  206. package/dist/domain/hopperValues.js +108 -8
  207. package/dist/domain/javascriptApplicationAnalysis.js +4 -7
  208. package/dist/domain/javascriptApplicationEvidenceSchemas.js +4 -3
  209. package/dist/domain/javascriptApplicationGraphSchemas.js +8 -7
  210. package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +9 -7
  211. package/dist/domain/javascriptApplicationVersionItems.js +12 -18
  212. package/dist/domain/javascriptAstValues.js +4 -0
  213. package/dist/domain/javascriptExportShapeComparison.js +1 -6
  214. package/dist/domain/javascriptExportShapeComparisonSchemas.js +6 -10
  215. package/dist/domain/javascriptExportShapeVariants.js +15 -2
  216. package/dist/domain/javascriptFeatureTraceSchemas.js +8 -7
  217. package/dist/domain/javascriptRuntimeObservation.js +14 -2
  218. package/dist/domain/javascriptRuntimeReconciliationMatching.js +8 -0
  219. package/dist/domain/javascriptRuntimeReconciliationParsing.js +4 -2
  220. package/dist/domain/javascriptRuntimeReconciliationResult.js +6 -4
  221. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +15 -4
  222. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +19 -18
  223. package/dist/domain/javascriptRuntimeStaticCandidates.js +18 -6
  224. package/dist/domain/javascriptSemanticAnalysis.js +57 -19
  225. package/dist/domain/javascriptSemanticAsyncEffects.js +39 -40
  226. package/dist/domain/javascriptSemanticCalls.js +46 -27
  227. package/dist/domain/javascriptSemanticChildProcesses.js +43 -50
  228. package/dist/domain/javascriptSemanticDataEffectHelpers.js +91 -18
  229. package/dist/domain/javascriptSemanticDataEffects.js +22 -10
  230. package/dist/domain/javascriptSemanticGraphSchemas.js +8 -6
  231. package/dist/domain/javascriptSemanticObjects.js +13 -3
  232. package/dist/domain/javascriptSemanticProjection.js +144 -38
  233. package/dist/domain/javascriptSemanticPromises.js +14 -27
  234. package/dist/domain/javascriptSemanticQuerySchemas.js +6 -9
  235. package/dist/domain/javascriptSemanticResources.js +2 -5
  236. package/dist/domain/javascriptSemanticState.js +4 -0
  237. package/dist/domain/javascriptSemanticTraceSchemas.js +2 -1
  238. package/dist/domain/javascriptSemanticTraversal.js +13 -5
  239. package/dist/domain/javascriptSemanticValues.js +10 -9
  240. package/dist/domain/javascriptSourceParser.js +5 -1
  241. package/dist/domain/javascriptStaticAnalysisCalls.js +8 -5
  242. package/dist/domain/javascriptStaticAnalysisHelpers.js +16 -7
  243. package/dist/domain/keyedArchive.js +181 -0
  244. package/dist/domain/managedApplicationGraph.js +4 -3
  245. package/dist/domain/managedArtifact.js +2 -1
  246. package/dist/domain/managedMemberComparison.js +18 -13
  247. package/dist/domain/managedMemberComparisonCoverage.js +2 -1
  248. package/dist/domain/managedMemberComparisonItems.js +27 -7
  249. package/dist/domain/managedMemberComparisonMatch.js +22 -6
  250. package/dist/domain/managedNativeVerificationMatch.js +2 -2
  251. package/dist/domain/managedNativeVerificationSchemas.js +7 -5
  252. package/dist/domain/managedReconstruction.js +6 -5
  253. package/dist/domain/nativeApiBoundary.js +7 -0
  254. package/dist/domain/nativeDataType.js +51 -0
  255. package/dist/domain/nativeInspection.js +0 -1
  256. package/dist/domain/nativeInstruction.js +82 -0
  257. package/dist/domain/nativeInvestigationGraph.js +9 -5
  258. package/dist/domain/nativeUiObservation.js +123 -0
  259. package/dist/domain/nativeValueFlow.js +17 -0
  260. package/dist/domain/nativeValueTrace.js +64 -0
  261. package/dist/domain/objcSwiftMetadata.js +39 -0
  262. package/dist/domain/peInspection.js +1 -0
  263. package/dist/domain/processCapture.js +5 -55
  264. package/dist/domain/processCaptureExample.js +0 -9
  265. package/dist/domain/processCaptureValidation.js +13 -144
  266. package/dist/domain/processComparison.js +3 -25
  267. package/dist/domain/processObservation.js +0 -29
  268. package/dist/domain/processScenario.js +28 -228
  269. package/dist/domain/processTraceDimensionProjection.js +0 -15
  270. package/dist/domain/processTraceEvaluation.js +0 -6
  271. package/dist/domain/protocolCapture.js +8 -36
  272. package/dist/domain/reconstructionCoverage.js +3 -2
  273. package/dist/domain/reconstructionObligationLedgerSchemas.js +4 -12
  274. package/dist/domain/reconstructionReadinessSchemas.js +4 -3
  275. package/dist/domain/reconstructionVerification.js +2 -1
  276. package/dist/domain/reconstructionVerificationSchemas.js +6 -13
  277. package/dist/domain/referenceSourceClassification.js +0 -110
  278. package/dist/domain/referenceSourceGraph.js +15 -5
  279. package/dist/domain/residualUnknown.js +3 -2
  280. package/dist/domain/runtimeIdentification.js +6 -5
  281. package/dist/domain/sourceMapContents.js +5 -0
  282. package/dist/domain/sourceToBundleComparison.js +3 -10
  283. package/dist/domain/sourceToBundleComparisonSchemas.js +7 -6
  284. package/dist/domain/sourceToBundleSignals.js +9 -3
  285. package/dist/domain/staticRuntimeCorrelation.js +5 -11
  286. package/dist/domain/webBundleAnalysis.js +17 -9
  287. package/dist/domain/webBundleAnalyzer.js +1 -1
  288. package/dist/domain/webCaptureDiff.js +5 -11
  289. package/dist/domain/webCaptureDiffSchemas.js +2 -1
  290. package/dist/domain/webMcpDiscovery.js +2 -1
  291. package/dist/dotnet/ManagedMemberInspectorCore.js +15 -7
  292. package/dist/dotnet/ManagedMemberInstructionDecoder.js +57 -40
  293. package/dist/dotnet/ManagedMemberRows.js +2 -0
  294. package/dist/dotnet/ManagedMethodBodyReader.js +15 -8
  295. package/dist/dotnet/ManagedPeReader.js +2 -0
  296. package/dist/generatedMcpToolCatalog.js +1 -1
  297. package/dist/generatedPackageMetadata.js +2 -2
  298. package/dist/ghidra/GhidraAnalysisProfile.js +15 -5
  299. package/dist/ghidra/GhidraClient.js +38 -8
  300. package/dist/ghidra/GhidraFunctionValues.js +56 -20
  301. package/dist/ghidra/GhidraInstallation.js +7 -4
  302. package/dist/ghidra/GhidraInventoryValues.js +44 -9
  303. package/dist/ghidra/GhidraLauncher.js +18 -3
  304. package/dist/ghidra/GhidraProvider.js +23 -2
  305. package/dist/ghidra/GhidraRequestQueue.js +45 -4
  306. package/dist/ghidra/GhidraSessionValues.js +5 -0
  307. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  308. package/dist/hopper/HopperProvider.js +29 -6
  309. package/dist/hopper/HopperTargetLease.js +18 -4
  310. package/dist/logger.js +0 -13
  311. package/dist/main/messages.js +0 -1
  312. package/dist/main/reload.js +3 -32
  313. package/dist/main/shutdown.js +1 -2
  314. package/dist/main/transport.js +0 -17
  315. package/dist/main.js +0 -10
  316. package/dist/native/AppleDispatchMetadata.js +582 -0
  317. package/dist/native/AppleObjcProtocols.js +88 -0
  318. package/dist/native/AppleSwiftVtables.js +86 -0
  319. package/dist/native/CommandRunner.js +1 -1
  320. package/dist/native/NativeHostCapabilities.js +23 -0
  321. package/dist/native/NativeMacOSProvider.js +61 -9
  322. package/dist/native/NativeMachoInspection.js +39 -6
  323. package/dist/native/NativeUiHelperRuntime.js +42 -0
  324. package/dist/native/NativeUiObservation.js +174 -0
  325. package/dist/native/parsers/codesign.js +4 -1
  326. package/dist/native/parsers/dyldInfo.js +51 -25
  327. package/dist/native/parsers/lipo.js +13 -4
  328. package/dist/native/parsers/otool.js +84 -39
  329. package/dist/native/parsers/plist.js +2 -1
  330. package/dist/process/ExecFileOutput.js +5 -1
  331. package/dist/process/ProcessOwnership.js +69 -33
  332. package/dist/process/ProcessOwnershipObservation.js +31 -12
  333. package/dist/process/ProviderProcess.js +4 -2
  334. package/dist/reference/ReferenceSourceReaderEntries.js +48 -31
  335. package/dist/reference/ReferenceSourceReaderErrors.js +24 -0
  336. package/dist/reference/ReferenceSourceReaderFile.js +11 -5
  337. package/dist/reference/ReferenceSourceReaderValidate.js +22 -8
  338. package/dist/server/createServer.js +7 -62
  339. package/dist/server/registerApplicationTools/helpers.js +2 -9
  340. package/dist/server/registerApplicationTools.js +0 -4
  341. package/dist/server/registerArtifactComparisonTool.js +1 -1
  342. package/dist/server/registerBrowserScenarioTool.js +4 -2
  343. package/dist/server/registerBrowserTools.js +7 -7
  344. package/dist/server/registerBundleComparisonTool.js +1 -1
  345. package/dist/server/registerCloseLifecycleTool.js +1 -1
  346. package/dist/server/registerElectronTools.js +10 -4
  347. package/dist/server/registerEnhancedTools.js +20 -12
  348. package/dist/server/registerEvidenceTools.js +4 -28
  349. package/dist/server/registerFunctionComparisonTool.js +1 -1
  350. package/dist/server/registerInvestigationTools.js +6 -6
  351. package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -2
  352. package/dist/server/registerManagedTools.js +28 -14
  353. package/dist/server/registerManagedWorkflowTools.js +0 -2
  354. package/dist/server/registerProcessComparisonTool.js +1 -3
  355. package/dist/server/registerSessionRecordTools.js +9 -9
  356. package/dist/server/registerSessionStatusTool.js +1 -1
  357. package/dist/server/registerSessionTools.js +28 -57
  358. package/dist/server/sessionAvailabilityPolicy.js +2 -3
  359. package/dist/server/sessionToolPolicies.js +0 -4
  360. package/dist/server/toolResult.js +8 -10
  361. package/package.json +32 -22
  362. package/skills/reverse-engineer-anything/SKILL.md +15 -11
  363. package/skills/reverse-engineer-anything/references/evidence-workflows.md +3 -2
  364. package/skills/reverse-engineer-anything/references/javascript-applications.md +3 -2
  365. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +8 -6
  366. package/skills/reverse-engineer-anything/references/runtime-observation.md +15 -11
  367. package/dist/application/CommandShimReplay.js +0 -152
  368. package/dist/application/ConfiguredRoots.js +0 -19
  369. package/dist/application/InstrumentedJavaScriptReplayHost.js +0 -36
  370. package/dist/application/JavaScriptReplayPermission.js +0 -16
  371. package/dist/application/JavaScriptReplayPlanning.js +0 -207
  372. package/dist/application/JavaScriptReplayService.js +0 -274
  373. package/dist/application/LoopbackReplay.js +0 -389
  374. package/dist/application/LoopbackReplayRecorder.js +0 -129
  375. package/dist/application/ManagedRuntimeCorrelationService.js +0 -104
  376. package/dist/application/NodeRuntimeCharacterizationService.js +0 -191
  377. package/dist/application/PermissionAuthority.js +0 -268
  378. package/dist/application/PermissionConfiguration.js +0 -26
  379. package/dist/application/PermissionFailure.js +0 -5
  380. package/dist/application/ProcessCaptureAuthority.js +0 -24
  381. package/dist/application/ProcessCapturePermission.js +0 -13
  382. package/dist/application/ProcessCheckpoints.js +0 -178
  383. package/dist/application/ProcessReactiveCoordinator.js +0 -223
  384. package/dist/application/ProcessReactiveEffects.js +0 -153
  385. package/dist/application/ProcessReactiveHarness.js +0 -106
  386. package/dist/application/ProcessReactiveObservations.js +0 -105
  387. package/dist/application/ProjectPermissionStore.js +0 -199
  388. package/dist/application/RuntimeExecutableDiagnostics.js +0 -198
  389. package/dist/application/Upgrade.js +0 -134
  390. package/dist/browser/SensitiveTextCapture.js +0 -8
  391. package/dist/cliPolicyCommands.js +0 -185
  392. package/dist/config/browserScenario.js +0 -77
  393. package/dist/config/electronAutomation.js +0 -35
  394. package/dist/config/javascriptReplay.js +0 -41
  395. package/dist/config/managedRuntime.js +0 -25
  396. package/dist/config/passiveObservation.js +0 -87
  397. package/dist/config/permissions.js +0 -23
  398. package/dist/config/processCapture.js +0 -47
  399. package/dist/contracts/replayMachineExample.js +0 -37
  400. package/dist/domain/javascriptExportInstrumentation.js +0 -95
  401. package/dist/domain/javascriptReplay.js +0 -360
  402. package/dist/domain/managedRuntimeCorrelation.js +0 -181
  403. package/dist/domain/nodeRuntimeCharacterization.js +0 -63
  404. package/dist/domain/permissionPolicy.js +0 -176
  405. package/dist/domain/processCaptureReactiveSchema.js +0 -68
  406. package/dist/domain/processCaptureReactiveValidation.js +0 -180
  407. package/dist/domain/processReactiveCheckpointDataflow.js +0 -32
  408. package/dist/domain/processReactiveMatching.js +0 -196
  409. package/dist/domain/processReactiveRuntime.js +0 -116
  410. package/dist/domain/processReactiveScenario.js +0 -296
  411. package/dist/domain/processReactiveScenarioPreflight.js +0 -95
  412. package/dist/domain/processReactiveTransition.js +0 -187
  413. package/dist/domain/replayMachine.js +0 -320
  414. package/dist/domain/replayMachineRun.js +0 -168
  415. package/dist/domain/replayMachineRuntime.js +0 -296
  416. package/dist/domain/replayMachineValues.js +0 -84
  417. package/dist/domain/runtimeCharacterization.js +0 -84
  418. package/dist/replay/JavaScriptReplayWorker.js +0 -382
  419. package/dist/replay/JavaScriptReplayWorkerTypes.js +0 -1
  420. package/dist/replay/LinuxJavaScriptReplayRunner.js +0 -216
  421. package/dist/replay/LinuxJavaScriptReplaySandbox.js +0 -121
  422. package/dist/replay/LinuxRuntimeClosure.js +0 -44
  423. package/dist/replay/LinuxSeccompPolicy.js +0 -40
  424. package/dist/replay/ReplayOutcome.js +0 -104
  425. package/dist/replay/ReplayProcessLifecycle.js +0 -96
  426. package/dist/replay/ReplaySeccompFile.js +0 -29
  427. package/dist/replay/ReplayWorkerProtocol.js +0 -58
  428. package/dist/replay/SystemJavaScriptReplayHost.js +0 -153
  429. package/dist/server/ProcessCaptureElicitation.js +0 -153
  430. package/dist/server/registerApplicationTools/characterization.js +0 -46
  431. package/dist/server/registerApplicationTools/controlledReplay.js +0 -31
  432. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +0 -29
  433. package/dist/server/registerReplayMachineTool.js +0 -14
  434. 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, parent) => {
42
+ enter: (node) => {
41
43
  const callableId = semanticCallableIdForNode(node);
42
44
  if (callableId !== null && callableIds.has(callableId))
43
45
  callableStack.push(callableId);
44
- if (!t.isCallExpression(node) && !t.isOptionalCallExpression(node))
45
- return;
46
- const ownerCallableId = callableStack.at(-1) ?? null;
47
- collectEvent(node, ownerCallableId, state, events);
48
- collectTimer({ node, parent, ownerCallableId, state, output: timers });
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 = memberCallee(node);
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 = literalString(eventArgument);
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, parent, ownerCallableId, state, output } = input;
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
- ? assignedBindingId(parent, node, state)
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" || candidate.handleBindingId === null)
159
+ if (candidate.kind !== "schedule")
146
160
  continue;
147
- const existing = schedulesByBinding.get(candidate.handleBindingId) ?? [];
148
- existing.push(candidate);
149
- schedulesByBinding.set(candidate.handleBindingId, existing);
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, parent, context);
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, parent, context) => {
95
- const identifier = t.isVariableDeclarator(parent) &&
96
- parent.init === node &&
97
- t.isIdentifier(parent.id)
98
- ? parent.id
99
- : t.isAssignmentExpression(parent) &&
100
- parent.right === node &&
101
- t.isIdentifier(parent.left)
102
- ? parent.left
103
- : null;
104
- if (identifier === null)
105
- return;
106
- const binding = resolveSemanticBindingState(context.state, identifier, identifier.name);
107
- const identifierRange = range(identifier);
108
- const definition = binding?.definitions.find(({ location }) => location.start.line === identifierRange.start.line &&
109
- location.start.column === identifierRange.start.column &&
110
- location.end.line === identifierRange.end.line &&
111
- location.end.column === identifierRange.end.column);
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, propertyName, range, } from "./javascriptStaticAnalysisHelpers.js";
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, parent) => {
24
+ enter: (node) => {
23
25
  const callableId = semanticCallableIdForNode(node);
24
26
  if (callableId !== null && admittedCallables.has(callableId))
25
27
  callableStack.push(callableId);
26
- if (!t.isCallExpression(node) && !t.isOptionalCallExpression(node))
27
- return;
28
- const method = childProcessMethod(node.callee, state);
29
- if (method === null)
30
- return;
31
- output.push({
32
- node,
33
- method,
34
- ownerCallableId: callableStack.at(-1) ?? null,
35
- resultBindingId: assignedBindingId(parent, node, state),
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 = literalString(candidate.node.arguments[0]);
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
- if (spawn.resultBindingId === null)
67
- continue;
68
- const existing = spawnsByBinding.get(spawn.resultBindingId) ?? [];
69
- existing.push(spawn);
70
- spawnsByBinding.set(spawn.resultBindingId, existing);
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 = memberCallee(node);
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
- ? (literalString(node.arguments[0]) ?? "SIGTERM")
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 ? "complete" : "partial",
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 = literalString(argument);
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
- propertyName(property.key) === name) ?? null;
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, semanticStaticPropertyName, } from "./javascriptSemanticProjection.js";
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
- for (let index = context.ancestors.length - 1; index >= 0; index -= 1) {
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, propertyName, range, } from "./javascriptStaticAnalysisHelpers.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, 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 bindingId = request.operation.resultBindingId;
142
- if (bindingId === null)
143
- continue;
144
- const existing = requestsByBinding.get(bindingId) ?? [];
145
- existing.push(request);
146
- requestsByBinding.set(bindingId, existing);
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 ? "complete" : "partial",
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
- const name = propertyName(property.key);
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 [