rea-agents 6.2.0 → 6.4.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 (636) hide show
  1. package/README.md +24 -23
  2. package/bridge/ghidra/ReaGhidraApplySeeds.java +151 -0
  3. package/bridge/ghidra/ReaGhidraBridge.java +597 -209
  4. package/bridge/ghidra/ReaGhidraNoReturnFix.java +123 -0
  5. package/bridge/hopper_bridge.py +2 -0
  6. package/dist/adb/AdbConfiguration.js +88 -0
  7. package/dist/adb/AdbDeviceOutput.js +186 -0
  8. package/dist/adb/AdbProvider.js +1190 -0
  9. package/dist/adb/AdbShellOutput.js +309 -0
  10. package/dist/android/AndroidTargetSnapshot.js +104 -22
  11. package/dist/android/JadxConfiguration.js +44 -24
  12. package/dist/android/JadxProvider.js +59 -21
  13. package/dist/android/JadxSession.js +51 -9
  14. package/dist/apktool/ApktoolConfiguration.js +84 -0
  15. package/dist/apktool/ApktoolDecodeOutput.js +59 -0
  16. package/dist/apktool/ApktoolProvider.js +506 -0
  17. package/dist/application/AnalysisProvider.js +8 -2
  18. package/dist/application/AppBundleExecutable.js +27 -22
  19. package/dist/application/BinaryTargetResolver.js +85 -19
  20. package/dist/application/BrowserScenarioEvidence.js +2 -2
  21. package/dist/application/CapabilityInventory.js +11 -1
  22. package/dist/application/ClientConfigurationDocument.js +98 -0
  23. package/dist/application/ClientConfigurationFiles.js +91 -0
  24. package/dist/application/ClientRegistrationEnvironment.js +35 -0
  25. package/dist/application/ClientRegistrationStatus.js +75 -27
  26. package/dist/application/DirectAnalysis.js +14 -8
  27. package/dist/application/DirectAnalysisCleanup.js +1 -2
  28. package/dist/application/DirectAnalysisStatus.js +3 -6
  29. package/dist/application/Doctor.js +27 -34
  30. package/dist/application/DoctorDiagnostics.js +1 -1
  31. package/dist/application/EvidenceBundleCommands.js +6 -12
  32. package/dist/application/EvidenceBundleFiles.js +1 -1
  33. package/dist/application/GeminiClientSettings.js +139 -0
  34. package/dist/application/HermesClientHome.js +115 -0
  35. package/dist/application/HopperDownload.js +39 -0
  36. package/dist/application/InvestigationProviders.js +10 -4
  37. package/dist/application/JsonFiles.js +16 -15
  38. package/dist/application/JsonInputFile.js +252 -0
  39. package/dist/application/LinuxHopper.js +6 -13
  40. package/dist/application/MacHopper.js +172 -149
  41. package/dist/application/MipsElfAbiFlags.js +140 -0
  42. package/dist/application/ProviderOperationExecution.js +31 -0
  43. package/dist/application/ReconstructionObligationCandidates.js +16 -3
  44. package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
  45. package/dist/application/ReferenceSourceImport.js +76 -29
  46. package/dist/application/ReferenceSourceImportEntries.js +18 -9
  47. package/dist/application/ReferenceSourceImportPolicy.js +99 -23
  48. package/dist/application/ReferenceSourceImportTypes.js +30 -22
  49. package/dist/application/ReferenceSourceVcsAdapter.js +145 -30
  50. package/dist/application/RegularFileRead.js +103 -0
  51. package/dist/application/Setup.js +69 -10
  52. package/dist/application/SetupClientConfiguration.js +134 -23
  53. package/dist/application/SetupHost.js +102 -22
  54. package/dist/application/SetupPlan.js +18 -17
  55. package/dist/application/SetupSkill.js +81 -13
  56. package/dist/application/SupportedClients.js +305 -37
  57. package/dist/application/Uninstall.js +172 -8
  58. package/dist/application/UpdateMaintenance.js +23 -23
  59. package/dist/application/Utf8JsonInput.js +71 -0
  60. package/dist/application/WebScriptExportService.js +130 -57
  61. package/dist/application/WebSourceLocationService.js +3 -0
  62. package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
  63. package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
  64. package/dist/application/analysisView/AnalysisViewService.js +40 -2
  65. package/dist/application/android/AndroidAnalysisService.js +1 -1
  66. package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
  67. package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
  68. package/dist/application/binary/AnalysisClientCleanup.js +0 -24
  69. package/dist/application/binary/AnalysisSnapshotCache.js +5 -4
  70. package/dist/application/binary/BinarySession.js +18 -1
  71. package/dist/application/binary/BinarySessionOpen.js +9 -1
  72. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +2 -1
  73. package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
  74. package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
  75. package/dist/application/binaryDiagnostics/RecordedCrashService.js +2 -1
  76. package/dist/application/evm/EvmInterfaceService.js +3 -0
  77. package/dist/application/firmware/FirmwareAnalysisService.js +3 -0
  78. package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
  79. package/dist/application/javascript/ElectronActiveEvidence.js +2 -2
  80. package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
  81. package/dist/application/javascript/ElectronBoundaryGraphContext.js +3 -2
  82. package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
  83. package/dist/application/javascript/ElectronBoundaryGraphNative.js +20 -3
  84. package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
  85. package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -0
  86. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
  87. package/dist/application/javascript/JavaScriptApplicationService.js +23 -11
  88. package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
  89. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
  90. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -36
  91. package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
  92. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +74 -36
  93. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
  94. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
  95. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +53 -42
  96. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
  97. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +293 -238
  98. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +120 -28
  99. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -0
  100. package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
  101. package/dist/application/javascript/JavaScriptModuleRelationships.js +10 -20
  102. package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
  103. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
  104. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +11 -5
  105. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +206 -66
  106. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -1
  107. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +18 -23
  108. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +5 -2
  109. package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
  110. package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
  111. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +7 -5
  112. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +6 -4
  113. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
  114. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +1 -1
  115. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +29 -15
  116. package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
  117. package/dist/application/jeb/JebAnalysisPort.js +1 -0
  118. package/dist/application/jeb/JebAnalysisService.js +13 -0
  119. package/dist/application/managed/ManagedApplicationGraphService.js +1 -1
  120. package/dist/application/native/NativeCallRoutes.js +2 -4
  121. package/dist/application/native/NativeUiActionTrace.js +16 -8
  122. package/dist/application/native/NativeValueTrace.js +23 -6
  123. package/dist/application/process/ProcessCli.js +25 -20
  124. package/dist/artifacts/ArtifactPaths.js +129 -8
  125. package/dist/artifacts/ArtifactProvider.js +34 -31
  126. package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
  127. package/dist/artifacts/ArtifactReader.js +23 -0
  128. package/dist/artifacts/ArtifactResourceScope.js +100 -0
  129. package/dist/artifacts/AsarArtifactReader.js +218 -80
  130. package/dist/artifacts/AsarHeader.js +24 -0
  131. package/dist/artifacts/DirectoryArtifactReader.js +168 -65
  132. package/dist/artifacts/MachOSliceArtifactReader.js +116 -39
  133. package/dist/artifacts/NativeDmgArtifactReader.js +179 -87
  134. package/dist/artifacts/NativeDmgOwnership.js +109 -0
  135. package/dist/artifacts/SafeOutputTree.js +245 -70
  136. package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
  137. package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
  138. package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
  139. package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
  140. package/dist/artifacts/ZipArtifactReader.js +77 -27
  141. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +58 -18
  142. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +62 -24
  143. package/dist/artifacts/apple/KeyedArchiveReader.js +76 -49
  144. package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
  145. package/dist/artifacts/extraction/ArtifactExtraction.js +134 -92
  146. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +116 -50
  147. package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
  148. package/dist/artifacts/inventory/classify.js +87 -25
  149. package/dist/artifacts/inventory/hashStableRootArtifact.js +70 -0
  150. package/dist/artifacts/inventory/reader.js +13 -5
  151. package/dist/artifacts/inventory/scanCanonical.js +73 -30
  152. package/dist/artifacts/inventory/scanReader.js +43 -20
  153. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +72 -28
  154. package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
  155. package/dist/browser/BrowserScenarioPartialObservation.js +8 -2
  156. package/dist/browser/BrowserScenarioSecrets.js +52 -37
  157. package/dist/browser/CdpBrowserProvider.js +9 -3
  158. package/dist/browser/CdpCaptureDocuments.js +40 -6
  159. package/dist/browser/CdpCaptureDomSvg.js +210 -0
  160. package/dist/browser/CdpCaptureEventBodyShapes.js +4 -8
  161. package/dist/browser/CdpCaptureEventHandlers.js +26 -9
  162. package/dist/browser/CdpCaptureEvents.js +4 -9
  163. package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
  164. package/dist/browser/CdpConnection.js +22 -5
  165. package/dist/browser/CdpElectronInspection.js +2 -2
  166. package/dist/browser/CdpElectronProvider.js +4 -3
  167. package/dist/browser/CdpElectronScripts.js +2 -2
  168. package/dist/browser/CdpPageCapture.js +1 -1
  169. package/dist/browser/CdpTargetSession.js +30 -34
  170. package/dist/browser/CdpWebMcpDiscovery.js +48 -23
  171. package/dist/browser/ElectronFileScope.js +99 -9
  172. package/dist/browser/PlaywrightBrowserScenarioProvider.js +63 -7
  173. package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
  174. package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
  175. package/dist/browser/PlaywrightScenarioBrowser.js +208 -43
  176. package/dist/browser/PlaywrightScenarioSession.js +130 -65
  177. package/dist/browser/PlaywrightScenarioStorage.js +507 -0
  178. package/dist/browser/PngVisualDiff.js +198 -29
  179. package/dist/browser/WebSourceMapFetcher.js +35 -9
  180. package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
  181. package/dist/browser/assets/PublishWebScripts.js +75 -20
  182. package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
  183. package/dist/browser/assets/WebArtifactReads.js +23 -1
  184. package/dist/browser/assets/WebSourceLocationArtifacts.js +1 -0
  185. package/dist/browser/execution/CdpExecutionCapture.js +3 -3
  186. package/dist/browser/execution/CdpPreciseCoverage.js +5 -8
  187. package/dist/browser/history/HarCapture.js +14 -0
  188. package/dist/browser/history/HarCaptureProcess.js +2 -10
  189. package/dist/browser/history/MitmproxyCaptureAdapter.js +3 -1
  190. package/dist/browser/modules/WebModuleArtifacts.js +1 -0
  191. package/dist/cli/adbCommands.js +337 -0
  192. package/dist/cli/analysisViewCommands.js +39 -1
  193. package/dist/cli/apktoolCommands.js +53 -0
  194. package/dist/cli/artifactCommands.js +8 -11
  195. package/dist/cli/binaryDiagnosticsCommands.js +19 -1
  196. package/dist/cli/browserAdvancedCommands.js +65 -36
  197. package/dist/cli/coreAnalysisCommands.js +2 -2
  198. package/dist/cli/coreBinaryCommands.js +12 -13
  199. package/dist/cli/coreNativeCommands.js +1 -14
  200. package/dist/cli/electronCommands.js +14 -10
  201. package/dist/cli/evmCommands.js +13 -4
  202. package/dist/cli/firmwareCommands.js +7 -2
  203. package/dist/cli/javascriptApplicationAnalysis.js +19 -13
  204. package/dist/cli/javascriptRecoveryCommands.js +22 -15
  205. package/dist/cli/jebCommands.js +99 -0
  206. package/dist/cli/jsonOutput.js +12 -4
  207. package/dist/cli/referenceSourceImportStatus.js +7 -0
  208. package/dist/cli/setupCommands.js +15 -3
  209. package/dist/cli/streamedJsonOutput.js +83 -4
  210. package/dist/cli/utilityCommands.js +68 -22
  211. package/dist/cli/webScriptCommands.js +20 -1
  212. package/dist/cli/webSourceLocationCommands.js +21 -9
  213. package/dist/cli.js +11 -2
  214. package/dist/cliBrowserScenarioCommands.js +2 -1
  215. package/dist/cliCommandNames.js +32 -0
  216. package/dist/cliJsonInput.js +47 -34
  217. package/dist/cliObservationOptions.js +7 -0
  218. package/dist/composition/adb.js +3 -0
  219. package/dist/composition/apktool.js +3 -0
  220. package/dist/composition/auxiliaryAnalysisProviders.js +5 -4
  221. package/dist/composition/binaryDiagnostics.js +4 -0
  222. package/dist/composition/browserScenario.js +2 -2
  223. package/dist/composition/directAnalysis.js +14 -7
  224. package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
  225. package/dist/composition/jeb.js +6 -0
  226. package/dist/config/environment.js +10 -0
  227. package/dist/config/ghidraLanguageOverride.js +9 -0
  228. package/dist/config/mcpInputSchemaProfile.js +27 -0
  229. package/dist/config/parseConfig.js +28 -1
  230. package/dist/contracts/adb/adbToolContracts.js +353 -0
  231. package/dist/contracts/advertisedInputExamples.js +48 -0
  232. package/dist/contracts/analysisDetail.js +10 -0
  233. package/dist/contracts/analysisViewToolContracts.js +17 -2
  234. package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
  235. package/dist/contracts/artifactComparisonExample.js +5 -5
  236. package/dist/contracts/artifactToolContracts.js +8 -5
  237. package/dist/contracts/browserToolContracts.js +1 -1
  238. package/dist/contracts/compactInputSchema.js +256 -0
  239. package/dist/contracts/errorSchemas.js +3 -1
  240. package/dist/contracts/functionComparisonExample.js +8 -0
  241. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  242. package/dist/contracts/inputSchemaPresentation.js +104 -13
  243. package/dist/contracts/javascript/electronToolContracts.js +16 -3
  244. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -2
  245. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +6 -3
  246. package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
  247. package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
  248. package/dist/contracts/jeb/jebToolContracts.js +64 -0
  249. package/dist/contracts/managed/managedToolContracts.js +3 -2
  250. package/dist/contracts/mobileApplicationGraphExamples.js +5 -5
  251. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
  252. package/dist/contracts/native/nativeToolContracts.js +1 -1
  253. package/dist/contracts/officialToolContracts.js +5 -5
  254. package/dist/contracts/sessionLifecycleInputs.js +4 -3
  255. package/dist/contracts/sessionStatusContract.js +3 -2
  256. package/dist/contracts/sessionToolContracts.js +5 -4
  257. package/dist/contracts/sessionToolSchemas.js +9 -4
  258. package/dist/contracts/toolContractExamples.js +6 -0
  259. package/dist/contracts/toolContractTypes.js +3 -0
  260. package/dist/contracts/toolContracts.js +6 -0
  261. package/dist/contracts/toolEffects.js +167 -0
  262. package/dist/contracts/toolOutputSchemaGroups.js +7 -5
  263. package/dist/contracts/toolOutputSchemaPrimitives.js +2 -5
  264. package/dist/contracts/toolSchemaMetadata.js +82 -7
  265. package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
  266. package/dist/domain/analysisErrorBase.js +5 -0
  267. package/dist/domain/analysisErrorCleanup.js +29 -0
  268. package/dist/domain/analysisErrorPresentation.js +18 -4
  269. package/dist/domain/analysisErrorProjection.js +4 -1
  270. package/dist/domain/analysisSnapshot.js +5 -2
  271. package/dist/domain/analysisView/analysisView.js +53 -5
  272. package/dist/domain/analysisView/binaryLayoutView.js +2 -0
  273. package/dist/domain/analysisView/javascriptApplicationView.js +2 -0
  274. package/dist/domain/analysisView/nativeFunctionView.js +155 -0
  275. package/dist/domain/android/androidApplication.js +25 -20
  276. package/dist/domain/android/androidPartialObservation.js +36 -0
  277. package/dist/domain/apktool/apktoolResourceAnalysis.js +77 -0
  278. package/dist/domain/apple/appleApplication.js +40 -23
  279. package/dist/domain/apple/appleBundleAnatomy.js +95 -28
  280. package/dist/domain/apple/dyldPaths.js +9 -1
  281. package/dist/domain/apple/dylibResolution.js +3 -3
  282. package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
  283. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
  284. package/dist/domain/artifactComparison.js +39 -11
  285. package/dist/domain/artifactGraph.js +6 -4
  286. package/dist/domain/artifactIdentity.js +37 -9
  287. package/dist/domain/artifactInspection.js +10 -50
  288. package/dist/domain/artifactIntegrityPolicy.js +10 -0
  289. package/dist/domain/artifactInventoryEvidence.js +16 -17
  290. package/dist/domain/artifactPathSyntax.js +1 -1
  291. package/dist/domain/binaryTarget.js +16 -0
  292. package/dist/domain/binaryTargetTypes.js +8 -1
  293. package/dist/domain/browserCompleteness.js +3 -2
  294. package/dist/domain/browserObservationSchemas.js +8 -4
  295. package/dist/domain/browserScenarioCaptureValues.js +2 -2
  296. package/dist/domain/browserScenarioNormalization.js +3 -3
  297. package/dist/domain/browserScenarioValues.js +3 -2
  298. package/dist/domain/callPath.js +8 -10
  299. package/dist/domain/canonicalDigest.js +7 -1
  300. package/dist/domain/canonicalJsonDigestSteps.js +34 -12
  301. package/dist/domain/canonicalOrdering.js +1 -13
  302. package/dist/domain/changedBehavior.js +2 -3
  303. package/dist/domain/compactStringIdentity.js +9 -0
  304. package/dist/domain/comparisonSemantics.js +0 -5
  305. package/dist/domain/digests.js +0 -3
  306. package/dist/domain/evidence.js +12 -6
  307. package/dist/domain/evidenceBundle.js +51 -33
  308. package/dist/domain/evidenceRecordSummary.js +144 -0
  309. package/dist/domain/firmware/firmwareAnalysis.js +4 -3
  310. package/dist/domain/functionComparison.js +2 -1
  311. package/dist/domain/functionComparisonNormalization.js +4 -3
  312. package/dist/domain/functionComparisonResults.js +2 -2
  313. package/dist/domain/functionDossierEvidence.js +2 -1
  314. package/dist/domain/hopperValues.js +11 -15
  315. package/dist/domain/inputIssueProjection.js +16 -1
  316. package/dist/domain/javascript/electronActiveObservation.js +4 -3
  317. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +14 -15
  318. package/dist/domain/javascript/electronStaticAnalysisIpc.js +20 -21
  319. package/dist/domain/javascript/electronStaticAnalysisNative.js +73 -41
  320. package/dist/domain/javascript/electronStaticAnalysisValues.js +24 -4
  321. package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
  322. package/dist/domain/javascript/javascriptApplicationAnalysis.js +6 -1
  323. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +18 -14
  324. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +4 -0
  325. package/dist/domain/javascript/javascriptApplicationGraph.js +91 -28
  326. package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
  327. package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
  328. package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
  329. package/dist/domain/javascript/javascriptApplicationVersionItems.js +72 -45
  330. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +16 -8
  331. package/dist/domain/javascript/javascriptAstFingerprint.js +60 -33
  332. package/dist/domain/javascript/javascriptAstValues.js +54 -0
  333. package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
  334. package/dist/domain/javascript/javascriptExportShapeComparison.js +3 -2
  335. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +31 -23
  336. package/dist/domain/javascript/javascriptExportShapeSelection.js +2 -2
  337. package/dist/domain/javascript/javascriptExportShapeVariants.js +3 -2
  338. package/dist/domain/javascript/javascriptFeatureSeed.js +5 -3
  339. package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
  340. package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
  341. package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -4
  342. package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
  343. package/dist/domain/javascript/javascriptNativeHandoff.js +12 -7
  344. package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
  345. package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
  346. package/dist/domain/javascript/javascriptRuntimeObservation.js +8 -5
  347. package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
  348. package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
  349. package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
  350. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +12 -6
  351. package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
  352. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +5 -5
  353. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -223
  354. package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
  355. package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
  356. package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
  357. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +15 -17
  358. package/dist/domain/javascript/javascriptSemanticAnalysis.js +379 -30
  359. package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
  360. package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
  361. package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
  362. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -2
  363. package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
  364. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
  365. package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
  366. package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
  367. package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
  368. package/dist/domain/javascript/javascriptSemanticFingerprints.js +43 -42
  369. package/dist/domain/javascript/javascriptSemanticGraph.js +205 -52
  370. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +21 -11
  371. package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
  372. package/dist/domain/javascript/javascriptSemanticIterationSources.js +139 -0
  373. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +774 -136
  374. package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
  375. package/dist/domain/javascript/javascriptSemanticMutationValues.js +98 -41
  376. package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
  377. package/dist/domain/javascript/javascriptSemanticObjects.js +9 -7
  378. package/dist/domain/javascript/javascriptSemanticPrimitives.js +7 -2
  379. package/dist/domain/javascript/javascriptSemanticProjection.js +72 -28
  380. package/dist/domain/javascript/javascriptSemanticPromises.js +15 -21
  381. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +100 -0
  382. package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
  383. package/dist/domain/javascript/javascriptSemanticQuery.js +33 -29
  384. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +4 -5
  385. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
  386. package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
  387. package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
  388. package/dist/domain/javascript/javascriptSemanticReturns.js +34 -48
  389. package/dist/domain/javascript/javascriptSemanticState.js +22 -2
  390. package/dist/domain/javascript/javascriptSemanticTraversal.js +25 -2
  391. package/dist/domain/javascript/javascriptSemanticValues.js +169 -30
  392. package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
  393. package/dist/domain/javascript/javascriptSourceMapPaths.js +11 -1
  394. package/dist/domain/javascript/javascriptSourceParser.js +34 -9
  395. package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
  396. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +13 -12
  397. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
  398. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
  399. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -15
  400. package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
  401. package/dist/domain/javascript/sourceToBundleComparison.js +7 -5
  402. package/dist/domain/javascript/sourceToBundleSignals.js +7 -7
  403. package/dist/domain/jeb/jebAnalysis.js +114 -0
  404. package/dist/domain/jsonSerialization.js +109 -55
  405. package/dist/domain/jsonShape.js +69 -31
  406. package/dist/domain/jsonValue.js +3 -0
  407. package/dist/domain/localPath.js +10 -4
  408. package/dist/domain/managed/managedApplicationGraph.js +47 -6
  409. package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
  410. package/dist/domain/managed/managedApplicationGraphNodes.js +94 -59
  411. package/dist/domain/managed/managedArtifact.js +1 -0
  412. package/dist/domain/managed/managedInspectionEvidence.js +13 -0
  413. package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
  414. package/dist/domain/native/nativeAotPe.js +1408 -0
  415. package/dist/domain/native/nativeCallObservation.js +2 -4
  416. package/dist/domain/native/nativeInstruction.js +21 -0
  417. package/dist/domain/native/nativeMetadataRecovery.js +79 -6
  418. package/dist/domain/native/nativeValueFlow.js +5 -11
  419. package/dist/domain/native/objcSwiftMetadata.js +15 -17
  420. package/dist/domain/native/peResources.js +94 -0
  421. package/dist/domain/nativeConvention.js +33 -0
  422. package/dist/domain/process/processCapture.js +102 -11
  423. package/dist/domain/process/processCaptureCoverage.js +8 -5
  424. package/dist/domain/process/processCaptureExample.js +67 -0
  425. package/dist/domain/process/processCaptureValidation.js +83 -3
  426. package/dist/domain/process/processComparison.js +0 -23
  427. package/dist/domain/process/processScenario.js +62 -10
  428. package/dist/domain/process/processTraceEvaluation.js +4 -4
  429. package/dist/domain/process/processTraceSpecification.js +1 -3
  430. package/dist/domain/propertyListKeys.js +3 -1
  431. package/dist/domain/providerCleanupError.js +6 -2
  432. package/dist/domain/reconstructionCoverage.js +2 -1
  433. package/dist/domain/reconstructionUnknowns.js +4 -3
  434. package/dist/domain/reconstructionVerification.js +3 -2
  435. package/dist/domain/referenceSourceGraph.js +32 -23
  436. package/dist/domain/referenceSourceImportParsing.js +40 -48
  437. package/dist/domain/referenceSourcePathIdentity.js +22 -0
  438. package/dist/domain/referenceSourceRequireBindings.js +137 -0
  439. package/dist/domain/residualUnknown.js +3 -2
  440. package/dist/domain/staticRuntimeCorrelation.js +2 -1
  441. package/dist/domain/swiftSymbolClassification.js +6 -1
  442. package/dist/domain/symbolAnalysis.js +17 -2
  443. package/dist/domain/unicodeCodePointOrder.js +6 -0
  444. package/dist/domain/webBundleAnalyzerInspection.js +23 -3
  445. package/dist/domain/webCaptureDiff.js +170 -30
  446. package/dist/domain/webCaptureDiffSchemas.js +2 -8
  447. package/dist/domain/webInventory.js +3 -2
  448. package/dist/domain/webMcpDiscovery.js +4 -3
  449. package/dist/domain/webScriptExport.js +1 -1
  450. package/dist/domain/webScriptExportError.js +10 -4
  451. package/dist/domain/webScriptExportPlan.js +7 -13
  452. package/dist/domain/zipPackageFormat.js +4 -1
  453. package/dist/domain/zodCollectionSteps.js +24 -0
  454. package/dist/dotnet/ManagedArtifactInspector.js +55 -43
  455. package/dist/dotnet/ManagedDecodeBudget.js +80 -0
  456. package/dist/dotnet/ManagedMemberInspector.js +13 -6
  457. package/dist/dotnet/ManagedMemberInspectorCore.js +2 -2
  458. package/dist/dotnet/ManagedMemberInstructionDecoder.js +5 -4
  459. package/dist/dotnet/ManagedMemberRows.js +9 -4
  460. package/dist/dotnet/ManagedMetadataHeaps.js +15 -5
  461. package/dist/dotnet/ManagedMetadataInventoryRows.js +20 -11
  462. package/dist/dotnet/ManagedMetadataLayout.js +10 -4
  463. package/dist/dotnet/ManagedMethodBodyReader.js +8 -3
  464. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +3 -2
  465. package/dist/dotnet/ManagedNativeBoundaryInspector.js +49 -34
  466. package/dist/dotnet/ManagedPeReader.js +41 -25
  467. package/dist/dotnet/ManagedReaderFailure.js +2 -1
  468. package/dist/dotnet/ManagedStaticProvider.js +65 -31
  469. package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
  470. package/dist/evaluation/AgentEvaluationReport.js +9 -5
  471. package/dist/evaluation/CodexAgentEval.js +43 -13
  472. package/dist/evm/EvmoleFailures.js +0 -2
  473. package/dist/evm/EvmoleInterfaceProvider.js +67 -2
  474. package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
  475. package/dist/filesystem/OwnedFileHandle.js +36 -0
  476. package/dist/filesystem/RegularFile.js +73 -0
  477. package/dist/filesystem/StableFileHash.js +46 -0
  478. package/dist/filesystem/readFileHandleChunks.js +26 -0
  479. package/dist/firmware/FirmwareCommand.js +25 -3
  480. package/dist/firmware/FirmwareFiles.js +23 -8
  481. package/dist/firmware/FirmwareProvider.js +156 -32
  482. package/dist/firmware/FirmwarePublication.js +24 -3
  483. package/dist/firmware/FirmwareRelease.js +1 -0
  484. package/dist/generatedPackageMetadata.js +2 -2
  485. package/dist/ghidra/GhidraAnalysisProfile.js +55 -4
  486. package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
  487. package/dist/ghidra/GhidraClient.js +90 -8
  488. package/dist/ghidra/GhidraDiagnostics.js +11 -8
  489. package/dist/ghidra/GhidraFunctionValues.js +26 -2
  490. package/dist/ghidra/GhidraInstallation.js +111 -10
  491. package/dist/ghidra/GhidraInventoryValues.js +23 -1
  492. package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
  493. package/dist/ghidra/GhidraLauncher.js +123 -58
  494. package/dist/ghidra/GhidraLoadImageAttest.js +49 -2
  495. package/dist/ghidra/GhidraMipsProfile.js +79 -0
  496. package/dist/ghidra/GhidraProvider.js +57 -9
  497. package/dist/ghidra/GhidraProviderCapabilities.js +18 -8
  498. package/dist/ghidra/GhidraProviderClient.js +282 -21
  499. package/dist/ghidra/GhidraSessionValues.js +9 -2
  500. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  501. package/dist/hopper/HopperCleanup.js +1 -1
  502. package/dist/hopper/HopperClient.js +15 -6
  503. package/dist/hopper/HopperMachOImage.js +2 -0
  504. package/dist/hopper/HopperProvider.js +13 -2
  505. package/dist/ida/IdaOperationRunner.js +10 -2
  506. package/dist/ida/IdaProvider.js +7 -0
  507. package/dist/ida/IdaSessionClient.js +7 -3
  508. package/dist/ida/IdaWorkspace.js +4 -2
  509. package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
  510. package/dist/inspector/V8InspectorCaptureProjection.js +46 -13
  511. package/dist/inspector/V8InspectorProvider.js +60 -8
  512. package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +326 -0
  513. package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +520 -0
  514. package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +63 -0
  515. package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +521 -0
  516. package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +116 -0
  517. package/dist/javascript/recovery/RecoveryFiles.js +18 -7
  518. package/dist/javascript/recovery/WakaruCommand.js +22 -9
  519. package/dist/javascript/recovery/WakaruExecution.js +11 -7
  520. package/dist/javascript/recovery/WakaruProvider.js +139 -16
  521. package/dist/javascript/recovery/WakaruPublication.js +14 -4
  522. package/dist/javascript/recovery/WakaruRelease.js +10 -3
  523. package/dist/javascript/recovery/WakaruReport.js +12 -7
  524. package/dist/javascript/recovery/WakaruVersion.js +24 -0
  525. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -3
  526. package/dist/javascript/sourceMaps/SourceMapDecoder.js +63 -7
  527. package/dist/javascript/sourceMaps/SourceMapFormat.js +15 -4
  528. package/dist/jeb/JebMcpConnection.js +179 -0
  529. package/dist/jeb/JebMcpEndpoint.js +40 -0
  530. package/dist/jeb/JebProvider.js +299 -0
  531. package/dist/main/shutdown.js +76 -32
  532. package/dist/main/transport.js +1 -1
  533. package/dist/mcpDoctor.js +15 -6
  534. package/dist/native/AppleDispatchCoverage.js +25 -12
  535. package/dist/native/AppleDispatchMetadata.js +14 -7
  536. package/dist/native/AppleMachoFixups.js +71 -15
  537. package/dist/native/AppleMachoSelection.js +23 -3
  538. package/dist/native/AppleObjcDispatchFacets.js +3 -3
  539. package/dist/native/AppleObjcProperties.js +17 -7
  540. package/dist/native/LldbCallTracer.js +241 -75
  541. package/dist/native/NativeMacOSProvider.js +100 -20
  542. package/dist/native/NativeMacOSProviderMetadata.js +1 -2
  543. package/dist/native/NativeMachoInspection.js +11 -7
  544. package/dist/native/NativeUiHelperRuntime.js +6 -1
  545. package/dist/native/NativeUiObservation.js +4 -3
  546. package/dist/native/pe/PeResourceLayout.js +120 -0
  547. package/dist/native/pe/PeResourceParser.js +286 -0
  548. package/dist/native/pe/PeResourcesProvider.js +63 -0
  549. package/dist/process/BoundedFileBytes.js +30 -7
  550. package/dist/process/DarwinProcessRunTokenReader.js +8 -3
  551. package/dist/process/OwnedCommand.js +4 -3
  552. package/dist/process/ProcessOwnership.js +104 -112
  553. package/dist/process/ProcessOwnershipObservation.js +104 -51
  554. package/dist/process/ProcessOwnershipProcessTree.js +4 -4
  555. package/dist/process/ProcessRunTokenObservations.js +48 -0
  556. package/dist/process/ProviderDiagnosticRedaction.js +17 -0
  557. package/dist/process/ProviderProcess.js +4 -3
  558. package/dist/process/capture/FilesystemSnapshot.js +116 -22
  559. package/dist/process/capture/ProcessCaptureLifecycle.js +363 -86
  560. package/dist/process/capture/ProcessCaptureProgress.js +62 -0
  561. package/dist/process/capture/ProcessFilesystemEffects.js +19 -4
  562. package/dist/process/capture/ProcessHarness.js +202 -47
  563. package/dist/process/capture/ProcessNormalization.js +3 -1
  564. package/dist/process/capture/ProcessScenarioRuntimeValidation.js +5 -2
  565. package/dist/process/capture/TerminalRenderer.js +24 -7
  566. package/dist/reference/ReferenceSourceReader.js +22 -5
  567. package/dist/reference/ReferenceSourceReaderEntries.js +114 -51
  568. package/dist/reference/ReferenceSourceReaderErrors.js +12 -0
  569. package/dist/reference/ReferenceSourceReaderFile.js +50 -10
  570. package/dist/reference/ReferenceSourceReaderValidate.js +4 -4
  571. package/dist/server/EvidenceMcpServer.js +36 -1
  572. package/dist/server/admittedToolOperation.js +9 -0
  573. package/dist/server/analysisAdmission.js +8 -0
  574. package/dist/server/contractToolHandler.js +21 -0
  575. package/dist/server/createServer.js +118 -47
  576. package/dist/server/registerAdbTools.js +36 -0
  577. package/dist/server/registerAnalysisViewTool.js +4 -9
  578. package/dist/server/registerAndroidTools.js +3 -12
  579. package/dist/server/registerApktoolTools.js +14 -0
  580. package/dist/server/registerApplicationTools/compareExportShapes.js +6 -7
  581. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  582. package/dist/server/registerApplicationTools/compareVersions.js +3 -2
  583. package/dist/server/registerApplicationTools/coverage.js +3 -2
  584. package/dist/server/registerApplicationTools/helpers.js +3 -2
  585. package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
  586. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -2
  587. package/dist/server/registerApplicationTools/traceFeature.js +3 -2
  588. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  589. package/dist/server/registerArtifactComparisonTool.js +5 -2
  590. package/dist/server/registerArtifactTools.js +2 -2
  591. package/dist/server/registerBinaryDiagnosticsTools.js +16 -4
  592. package/dist/server/registerBrowserScenarioTool.js +10 -7
  593. package/dist/server/registerBrowserTools.js +12 -9
  594. package/dist/server/registerBundleComparisonTool.js +16 -2
  595. package/dist/server/registerCloseLifecycleTool.js +36 -5
  596. package/dist/server/registerElectronTools.js +28 -10
  597. package/dist/server/registerEnhancedTools.js +78 -73
  598. package/dist/server/registerEvidenceTools.js +54 -46
  599. package/dist/server/registerEvmTools.js +4 -9
  600. package/dist/server/registerFirmwareTools.js +3 -11
  601. package/dist/server/registerFunctionComparisonTool.js +5 -2
  602. package/dist/server/registerJavaScriptRecoveryTool.js +4 -9
  603. package/dist/server/registerJavaScriptRuntimeObservationTools.js +9 -6
  604. package/dist/server/registerJebTools.js +16 -0
  605. package/dist/server/registerManagedTools.js +7 -4
  606. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -6
  607. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -2
  608. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +3 -2
  609. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +3 -2
  610. package/dist/server/registerOfficialTools.js +31 -25
  611. package/dist/server/registerPeResourcesTool.js +9 -0
  612. package/dist/server/registerProcessComparisonTool.js +5 -2
  613. package/dist/server/registerRecordedCrashTools.js +4 -9
  614. package/dist/server/registerSessionRecordTools.js +2 -1
  615. package/dist/server/registerSessionTools.js +58 -21
  616. package/dist/server/registerWebModuleTool.js +4 -9
  617. package/dist/server/registerWebNetworkCaptureTool.js +4 -9
  618. package/dist/server/registerWebRuntimeTools.js +6 -5
  619. package/dist/server/registerWebScriptTool.js +6 -3
  620. package/dist/server/registerWebSourceLocationTool.js +4 -9
  621. package/dist/server/toolResult.js +21 -2
  622. package/dist/windows/WindowsPrivateRuntime.js +12 -5
  623. package/install.sh +7 -4
  624. package/licenses/nativeaot-parser-MIT.txt +28 -0
  625. package/native/windows/build/manifest.json +2 -2
  626. package/native/windows/build/rea-windows-x64.node +0 -0
  627. package/package.json +38 -7
  628. package/scripts/rea.mjs +16 -1
  629. package/skills/reverse-engineer-anything/SKILL.md +52 -51
  630. package/skills/reverse-engineer-anything/references/connection-and-recovery.md +127 -0
  631. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -0
  632. package/skills/reverse-engineer-anything/references/javascript-applications.md +92 -13
  633. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +31 -1
  634. package/dist/artifacts/inventory/policy.js +0 -2
  635. package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
  636. package/dist/server/registerNativeTools.js +0 -6
@@ -1,64 +1,315 @@
1
1
  import * as t from "@babel/types";
2
2
  import { resolveSemanticBindingState, } from "./javascriptSemanticState.js";
3
- import { evaluateSemanticBinding } from "./javascriptSemanticValues.js";
4
- import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
5
- import { semanticStaticPropertyKey } from "./javascriptAstValues.js";
6
- /** Keep explicit property mutations outside the initializer-only value lattice. */
7
- export const collectSemanticMemberMutations = (program, state) => {
8
- const parents = new WeakMap();
9
- traverseJavaScriptAst(program, {
10
- enter: (node, parent) => {
11
- if (parent !== null)
12
- parents.set(node, parent);
13
- },
14
- });
15
- const markValue = (node, path, bindings, mutation) => {
16
- if (t.isIdentifier(node)) {
17
- const binding = resolveSemanticBindingState(state, node, node.name);
18
- if (binding === undefined || bindings.has(binding.bindingId))
19
- return;
20
- const value = evaluateSemanticBinding(binding, state);
21
- if (value.status === "literal" || value.status === "union")
22
- return;
23
- binding.mutatedPaths.push(path);
24
- const nested = new Set([...bindings, binding.bindingId]);
25
- for (const initializer of mutationInitializers(binding, mutation, parents))
26
- markValue(initializer.node, [...initializer.projection, ...path], nested, mutation);
3
+ import { clearSemanticPrimitiveBindingValues, evaluateSemanticBinding, evaluateSemanticExpression, } from "./javascriptSemanticValues.js";
4
+ import { semanticContainer, semanticSlotAtPath, } from "./javascriptSemanticSlots.js";
5
+ import { semanticClassCandidates, semanticClassPropertyReferences, semanticObjectPropertyReferences, } from "./javascriptSemanticObjectReferences.js";
6
+ import { semanticIterationSources } from "./javascriptSemanticIterationSources.js";
7
+ import { semanticCallableResultExpressions } from "./javascriptSemanticCallableResults.js";
8
+ import { createSemanticReturnedReferences } from "./javascriptSemanticReturnedReferences.js";
9
+ import { semanticMutationInitializers } from "./javascriptSemanticMutationInitializers.js";
10
+ import { semanticArrayIndex, SemanticPropertyPathCoverage, semanticPropertyPathKeyMatches, } from "./javascriptSemanticPropertyPaths.js";
11
+ import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
12
+ import { traverseJavaScriptAstSteps } from "./javascriptSemanticTraversal.js";
13
+ import { semanticStaticPropertyKey, semanticMemberWriteTargets, unwrapJavaScriptExpression, } from "./javascriptAstValues.js";
14
+ /** Preserve uncertainty from property writes and references exposed to calls, yielding during traversal and fixpoint iteration. */
15
+ export function* collectSemanticMemberMutationsSteps(program, state) {
16
+ const parents = state.parentsByNode;
17
+ const normalizePath = observableMutationPaths(state);
18
+ const returnedReferences = createSemanticReturnedReferences(state);
19
+ const recordedEffects = new Set();
20
+ const selections = new Map();
21
+ const coveringPaths = new Map();
22
+ let arrayIterationUnknown = false;
23
+ const pendingReferences = [];
24
+ const iterableReferences = [];
25
+ const iterableReferenceKeys = new WeakMap();
26
+ const deferIterable = (reference) => {
27
+ const keys = iterableReferenceKeys.get(reference.node) ?? new Set();
28
+ const key = JSON.stringify([
29
+ reference.projection,
30
+ reference.path,
31
+ reference.fallbackPath,
32
+ reference.effect,
33
+ reference.mutation?.start,
34
+ reference.mutation?.end,
35
+ reference.originAt?.start,
36
+ reference.originAt?.end,
37
+ reference.iterationOnly,
38
+ reference.requiredSources?.map((source) => [
39
+ source.node.start,
40
+ source.node.end,
41
+ source.projection,
42
+ ]),
43
+ reference.fallbackSources?.map((source) => [
44
+ source.node.start,
45
+ source.node.end,
46
+ source.projection,
47
+ ]),
48
+ [...reference.bindings].sort(compareUnicodeCodePoints),
49
+ ]);
50
+ if (keys.has(key))
27
51
  return;
52
+ keys.add(key);
53
+ iterableReferenceKeys.set(reference.node, keys);
54
+ iterableReferences.push(reference);
55
+ };
56
+ const markValue = (node, path, bindings, effect = "write", mutation, originAt = mutation) => {
57
+ const pending = [{ node, path, bindings, originAt }];
58
+ // Visit shallower alias traversals first so their exact prefixes suppress
59
+ // longer loop paths before those paths enumerate every assignment order.
60
+ for (let cursor = 0; cursor < pending.length; cursor++) {
61
+ const current = pending[cursor];
62
+ if (current === undefined)
63
+ break;
64
+ const expression = unwrapJavaScriptExpression(current.node).node;
65
+ if (t.isIdentifier(expression)) {
66
+ const binding = resolveSemanticBindingState(state, expression, expression.name);
67
+ if (binding === undefined) {
68
+ if ((expression.name === "Array" &&
69
+ (current.path[0] === "prototype" || current.path[0] === null)) ||
70
+ (["globalThis", "global", "window", "self"].includes(expression.name) &&
71
+ (current.path[0] === "Array" || current.path[0] === null) &&
72
+ (current.path[1] === "prototype" || current.path[1] === null)))
73
+ arrayIterationUnknown = true;
74
+ continue;
75
+ }
76
+ // An alias restored from a saved reference can revisit the same binding
77
+ // at an earlier capture or a shorter getter-receiver path. Only a
78
+ // repeated capture and path closes a cycle.
79
+ const lifetime = JSON.stringify([
80
+ binding.bindingId,
81
+ current.originAt?.start,
82
+ current.originAt?.end,
83
+ current.path,
84
+ ]);
85
+ if (current.bindings.has(lifetime))
86
+ continue;
87
+ // Union compatible copied-slot selections at each binding. Carrying every
88
+ // combination of exclusions through branch diamonds is exponential.
89
+ // Preserve paths that can change observed slots or Array prototype
90
+ // effects; canonicalize suffixes that cannot distinguish lattice facts.
91
+ let path = normalizePath(binding.bindingId, current.path, effect);
92
+ if (path === null)
93
+ continue;
94
+ const selectorIndex = path.findIndex((key) => key !== null && typeof key === "object");
95
+ const selector = path[selectorIndex];
96
+ if (selector !== null && typeof selector === "object") {
97
+ const selectionIdentity = JSON.stringify([
98
+ binding.bindingId,
99
+ effect,
100
+ path.map((key, index) => index === selectorIndex
101
+ ? { startIndex: selector.startIndex }
102
+ : key),
103
+ mutation?.start,
104
+ mutation?.end,
105
+ current.originAt?.start,
106
+ current.originAt?.end,
107
+ ]);
108
+ const previous = selections.get(selectionIdentity);
109
+ const excludedKeys = previous === undefined
110
+ ? selector.excludedKeys
111
+ : previous.filter((key) => selector.excludedKeys.includes(key));
112
+ if (previous !== undefined && excludedKeys.length === previous.length)
113
+ continue;
114
+ selections.set(selectionIdentity, excludedKeys);
115
+ path = path.map((key, index) => index === selectorIndex ? { ...selector, excludedKeys } : key);
116
+ }
117
+ // Keep an antichain of exact paths. Widening distinct member keys would
118
+ // also invalidate unrelated siblings that never reach this effect.
119
+ const pathState = JSON.stringify([
120
+ binding.bindingId,
121
+ effect,
122
+ // Short writes stop at owned literal slots, whereas longer writes
123
+ // reach shared children. Only equal-depth writes cover one another.
124
+ effect === "write" ? path.length : null,
125
+ mutation?.start,
126
+ mutation?.end,
127
+ current.originAt?.start,
128
+ current.originAt?.end,
129
+ ]);
130
+ let covering = coveringPaths.get(pathState);
131
+ if (covering === undefined) {
132
+ covering = new SemanticPropertyPathCoverage();
133
+ coveringPaths.set(pathState, covering);
134
+ }
135
+ if (!covering.retain(path))
136
+ continue;
137
+ const identity = JSON.stringify([
138
+ binding.bindingId,
139
+ effect,
140
+ path,
141
+ mutation?.start,
142
+ mutation?.end,
143
+ current.originAt?.start,
144
+ current.originAt?.end,
145
+ ]);
146
+ if (recordedEffects.has(identity))
147
+ continue;
148
+ // A recorded write invalidates the binding to a non-primitive value, so
149
+ // only its first write can target a primitive. Re-evaluating it would
150
+ // replay every earlier write and make repeated writes superlinear.
151
+ const value = effect === "write" && binding.mutatedPaths.length === 0
152
+ ? evaluateSemanticBinding(binding, state)
153
+ : undefined;
154
+ const primitiveWrite = value?.status === "literal" || value?.status === "union";
155
+ recordedEffects.add(identity);
156
+ const nested = new Set([...current.bindings, lifetime]);
157
+ const origins = current.originAt === undefined
158
+ ? binding
159
+ : semanticMutationInitializers(binding, current.originAt, parents);
160
+ if (!primitiveWrite) {
161
+ if (effect === "escape")
162
+ binding.escapedPaths.push({ path, node: mutation });
163
+ else
164
+ binding.mutatedPaths.push(path);
165
+ clearSemanticPrimitiveBindingValues(state);
166
+ for (const initializer of origins.initializers)
167
+ pending.push({
168
+ node: initializer.node,
169
+ path: [...initializer.projection, ...path],
170
+ bindings: nested,
171
+ originAt: initializer.node,
172
+ });
173
+ }
174
+ for (const initializer of origins.referenceInitializers) {
175
+ const copiedPath = copiedReferencePath(initializer, path, effect);
176
+ if (copiedPath === null)
177
+ continue;
178
+ pendingReferences.push({
179
+ initializer,
180
+ path: copiedPath,
181
+ bindings: nested,
182
+ effect,
183
+ originAt: initializer.node,
184
+ ...(mutation === undefined ? {} : { mutation }),
185
+ });
186
+ }
187
+ }
188
+ else if (t.isMemberExpression(expression) ||
189
+ t.isOptionalMemberExpression(expression)) {
190
+ pending.push({
191
+ node: expression.object,
192
+ path: [
193
+ semanticStaticPropertyKey(expression.property, expression.computed),
194
+ ...current.path,
195
+ ],
196
+ bindings: current.bindings,
197
+ originAt: current.originAt,
198
+ });
199
+ }
200
+ else {
201
+ for (const value of effect === "escape"
202
+ ? escapedReferenceLeaves(expression, current.path)
203
+ : expandedValues(expression, current.path, effect)) {
204
+ if (value.iterableFallbackPath !== undefined)
205
+ deferIterable({
206
+ node: value.node,
207
+ projection: [],
208
+ path: value.path,
209
+ fallbackPath: value.iterableFallbackPath,
210
+ bindings: current.bindings,
211
+ effect,
212
+ originAt: current.originAt,
213
+ ...(mutation === undefined ? {} : { mutation }),
214
+ });
215
+ else
216
+ pending.push({
217
+ ...value,
218
+ bindings: current.bindings,
219
+ originAt: current.originAt,
220
+ });
221
+ }
222
+ }
28
223
  }
29
- if (t.isMemberExpression(node) || t.isOptionalMemberExpression(node)) {
30
- const members = [];
31
- let current = node;
32
- while (t.isMemberExpression(current) ||
33
- t.isOptionalMemberExpression(current)) {
34
- members.push(semanticStaticPropertyKey(current.property, current.computed));
35
- current = current.object;
224
+ };
225
+ const markEscaped = (node, mutation, path = []) => markValue(node, path, new Set(), "escape", mutation);
226
+ function expandedValues(expression, path, effect) {
227
+ if (t.isArrayExpression(expression) &&
228
+ ((path[0] === "__proto__" && (effect === "escape" || path.length > 1)) ||
229
+ (path[0] === "constructor" && path[1] === "prototype")))
230
+ arrayIterationUnknown = true;
231
+ return referencedValues(expression, path, effect, state);
232
+ }
233
+ // Expanding a value below its references depends only on syntax, not on the
234
+ // escape site. Escaping an object reaches every method's results, so
235
+ // re-expanding it at each call through that object made N calls over N
236
+ // methods quadratic. Identifiers that resolve to the same binding and path
237
+ // are processed identically, so one stands for all of them.
238
+ const escapedLeaves = new WeakMap();
239
+ function escapedReferenceLeaves(root, rootPath) {
240
+ // Parser recovery can leave an argument hole, which expands to nothing.
241
+ if (!t.isNode(root))
242
+ return [];
243
+ const rootKey = JSON.stringify(rootPath);
244
+ const cached = escapedLeaves.get(root)?.get(rootKey);
245
+ if (cached !== undefined)
246
+ return cached;
247
+ const leaves = [];
248
+ const leafIdentities = new Set();
249
+ const expanded = new WeakMap();
250
+ const pending = [...expandedValues(root, rootPath, "escape")];
251
+ for (let cursor = 0; cursor < pending.length; cursor++) {
252
+ const value = pending[cursor];
253
+ if (value === undefined)
254
+ break;
255
+ const node = unwrapJavaScriptExpression(value.node).node;
256
+ if (!t.isNode(node))
257
+ continue;
258
+ const pathKey = JSON.stringify(value.path);
259
+ if (t.isIdentifier(node) && value.iterableFallbackPath === undefined) {
260
+ const binding = resolveSemanticBindingState(state, node, node.name);
261
+ const identity = JSON.stringify([
262
+ binding === undefined ? null : binding.bindingId,
263
+ binding === undefined ? node.name : null,
264
+ pathKey,
265
+ ]);
266
+ if (leafIdentities.has(identity))
267
+ continue;
268
+ leafIdentities.add(identity);
269
+ leaves.push(value);
270
+ }
271
+ else if (value.iterableFallbackPath !== undefined ||
272
+ t.isIdentifier(node) ||
273
+ t.isMemberExpression(node) ||
274
+ t.isOptionalMemberExpression(node))
275
+ leaves.push(value);
276
+ else {
277
+ const paths = expanded.get(node) ?? new Set();
278
+ if (paths.has(pathKey))
279
+ continue;
280
+ paths.add(pathKey);
281
+ expanded.set(node, paths);
282
+ for (const reference of expandedValues(node, value.path, "escape"))
283
+ pending.push(reference);
36
284
  }
37
- markValue(current, [...members.reverse(), ...path], bindings, mutation);
38
- return;
39
285
  }
40
- for (const value of referencedValues(node, path))
41
- markValue(value.node, value.path, bindings, mutation);
286
+ const byPath = escapedLeaves.get(root) ?? new Map();
287
+ byPath.set(rootKey, leaves);
288
+ escapedLeaves.set(root, byPath);
289
+ return leaves;
290
+ }
291
+ const markReceiver = (callee, mutation) => {
292
+ const expression = unwrapJavaScriptExpression(callee).node;
293
+ if (t.isMemberExpression(expression) ||
294
+ t.isOptionalMemberExpression(expression))
295
+ markEscaped(expression.object, mutation);
42
296
  };
43
297
  const markTarget = (node, mutation) => {
44
- if (t.isMemberExpression(node) || t.isOptionalMemberExpression(node))
45
- markValue(node.object, [semanticStaticPropertyKey(node.property, node.computed)], new Set(), mutation);
46
- else if (t.isRestElement(node))
47
- markTarget(node.argument, mutation);
48
- else if (t.isAssignmentPattern(node))
49
- markTarget(node.left, mutation);
50
- else if (t.isArrayPattern(node)) {
51
- for (const element of node.elements)
52
- if (element !== null)
53
- markTarget(element, mutation);
54
- }
55
- else if (t.isObjectPattern(node)) {
56
- for (const property of node.properties)
57
- markTarget(t.isRestElement(property) ? property.argument : property.value, mutation);
58
- }
298
+ for (const target of semanticMemberWriteTargets(node))
299
+ markValue(target.object, [semanticStaticPropertyKey(target.property, target.computed)], new Set(), "write", mutation);
59
300
  };
60
- traverseJavaScriptAst(program, {
61
- enter: (node) => {
301
+ yield* traverseJavaScriptAstSteps(program, {
302
+ enter: (node, parent) => {
303
+ for (const source of semanticIterationSources(node, parent))
304
+ deferIterable({
305
+ ...source,
306
+ path: source.projection,
307
+ fallbackPath: source.projection,
308
+ bindings: new Set(),
309
+ effect: "escape",
310
+ originAt: source.mutation,
311
+ iterationOnly: source.kind === "iteration",
312
+ });
62
313
  if (t.isAssignmentExpression(node))
63
314
  markTarget(node.left, node);
64
315
  else if (t.isUpdateExpression(node))
@@ -67,96 +318,209 @@ export const collectSemanticMemberMutations = (program, state) => {
67
318
  markTarget(node.argument, node);
68
319
  else if (t.isForOfStatement(node) || t.isForInStatement(node))
69
320
  markTarget(node.left, node);
321
+ else if (t.isCallExpression(node) ||
322
+ t.isOptionalCallExpression(node) ||
323
+ t.isNewExpression(node)) {
324
+ for (const source of returnedReferences(node.callee))
325
+ markEscaped(source.node, node, source.projection);
326
+ for (const argument of node.arguments)
327
+ if (t.isSpreadElement(argument))
328
+ deferIterable({
329
+ node: argument.argument,
330
+ projection: [],
331
+ path: [null],
332
+ fallbackPath: [],
333
+ bindings: new Set(),
334
+ effect: "escape",
335
+ mutation: node,
336
+ originAt: node,
337
+ });
338
+ else
339
+ markEscaped(argument, node);
340
+ // Constructing a member does not pass its container as `this`.
341
+ if (!t.isNewExpression(node))
342
+ markReceiver(node.callee, node);
343
+ }
344
+ else if (t.isTaggedTemplateExpression(node)) {
345
+ markReceiver(node.tag, node);
346
+ for (const expression of node.quasi.expressions)
347
+ markEscaped(expression, node);
348
+ }
70
349
  },
71
350
  });
72
- };
73
- const statementPosition = (statement, parents) => {
74
- const parent = parents.get(statement);
75
- if (!t.isProgram(parent) && !t.isBlockStatement(parent))
76
- return null;
77
- const index = parent.body.indexOf(statement);
78
- return index < 0 ? null : { body: parent.body, index };
79
- };
80
- const directInitializerPosition = (node, parents) => {
81
- const parent = parents.get(node);
82
- if (t.isVariableDeclarator(parent) && parent.init === node) {
83
- const declaration = parents.get(parent);
84
- return t.isVariableDeclaration(declaration)
85
- ? statementPosition(declaration, parents)
86
- : null;
87
- }
88
- if (t.isAssignmentExpression(parent) &&
89
- parent.operator === "=" &&
90
- parent.right === node &&
91
- t.isIdentifier(parent.left)) {
92
- const statement = parents.get(parent);
93
- return t.isExpressionStatement(statement) && statement.expression === parent
94
- ? statementPosition(statement, parents)
95
- : null;
351
+ // A later effect can make a previously defined destructuring source uncertain.
352
+ // Reconsider defaults and iterable origins until their effects are stable.
353
+ while (pendingReferences.length > 0 || iterableReferences.length > 0) {
354
+ const effectsBefore = recordedEffects.size;
355
+ const iterablesBefore = iterableReferences.length;
356
+ const iterationBefore = arrayIterationUnknown;
357
+ for (const [index, reference] of pendingReferences.splice(0).entries()) {
358
+ if (index % 64 === 0)
359
+ yield;
360
+ const { initializer } = reference;
361
+ if (referenceSourcesInactive(initializer, state))
362
+ pendingReferences.push(reference);
363
+ else if (t.isForOfStatement(initializer.node))
364
+ deferIterable({
365
+ node: initializer.node.right,
366
+ projection: [],
367
+ path: [null, ...reference.path],
368
+ fallbackPath: [],
369
+ bindings: reference.bindings,
370
+ effect: reference.effect,
371
+ originAt: initializer.node,
372
+ ...(reference.mutation === undefined
373
+ ? {}
374
+ : { mutation: reference.mutation }),
375
+ });
376
+ else if (initializer.copyKind === "array-rest" &&
377
+ initializer.copyProjectionOffset !== undefined) {
378
+ const offset = initializer.copyProjectionOffset;
379
+ const projection = initializer.projection.slice(0, offset);
380
+ deferIterable({
381
+ node: initializer.node,
382
+ projection,
383
+ path: reference.path,
384
+ fallbackPath: projection,
385
+ bindings: reference.bindings,
386
+ effect: reference.effect,
387
+ originAt: reference.originAt,
388
+ ...(reference.mutation === undefined
389
+ ? {}
390
+ : { mutation: reference.mutation }),
391
+ });
392
+ }
393
+ else
394
+ markValue(initializer.node, reference.path, reference.bindings, reference.effect, reference.mutation, reference.originAt);
395
+ }
396
+ for (const [index, reference] of [...iterableReferences].entries()) {
397
+ if (index % 64 === 0)
398
+ yield;
399
+ if (referenceSourcesInactive(reference, state))
400
+ continue;
401
+ if (reference.iterationOnly) {
402
+ const expanded = expandedIterationReferences(reference, state);
403
+ if (expanded !== null) {
404
+ for (const selected of expanded)
405
+ deferIterable(selected);
406
+ continue;
407
+ }
408
+ }
409
+ const slot = selectedReferenceSlot(reference, state);
410
+ // Custom iteration can yield the iterable itself as well as any child.
411
+ // Treat its root as escaped, including writes through yielded references.
412
+ const knownArray = !arrayIterationUnknown &&
413
+ slot?.value.status === "array" &&
414
+ slot.value.items.every((item) => semanticArrayIndex(item.name) !== null);
415
+ if (knownArray && reference.iterationOnly)
416
+ continue;
417
+ markValue(reference.node, knownArray ? reference.path : reference.fallbackPath, reference.bindings, knownArray ? reference.effect : "escape", reference.mutation, reference.originAt);
418
+ }
419
+ if (recordedEffects.size === effectsBefore &&
420
+ iterableReferences.length === iterablesBefore &&
421
+ arrayIterationUnknown === iterationBefore)
422
+ break;
96
423
  }
97
- return null;
98
- };
99
- const directMutationPosition = (node, parents) => {
100
- if (!t.isAssignmentExpression(node) &&
101
- !t.isUpdateExpression(node) &&
102
- !t.isUnaryExpression(node, { operator: "delete" }))
424
+ // Gathering effects can evaluate a primitive projection before its object
425
+ // escapes. Final values must use the completed mutation state.
426
+ clearSemanticPrimitiveBindingValues(state);
427
+ }
428
+ const referenceSourcesInactive = (reference, state) => reference.requiredSources?.some((source) => selectedReferenceSlot(source, state, source.node)?.presence === "absent") === true ||
429
+ reference.fallbackSources?.some((source) => {
430
+ // Selection precedes effects through the chosen reference. A later escape
431
+ // cannot make a fallback that was excluded at destructuring reachable.
432
+ const slot = selectedReferenceSlot(source, state, source.node);
433
+ return (slot?.presence === "present" &&
434
+ (slot.value.status === "literal" ||
435
+ slot.value.status === "union" ||
436
+ slot.value.status === "object" ||
437
+ slot.value.status === "array"));
438
+ }) === true;
439
+ const expandedIterationReferences = (reference, state) => {
440
+ if (!t.isForOfStatement(reference.mutation))
103
441
  return null;
104
- const statement = parents.get(node);
105
- return t.isExpressionStatement(statement) && statement.expression === node
106
- ? statementPosition(statement, parents)
107
- : null;
108
- };
109
- const mutationInitializers = (binding, mutation, parents) => {
110
- if (binding.initializers.length < 2)
111
- return binding.initializers;
112
- const mutationPosition = directMutationPosition(mutation, parents);
113
- if (mutationPosition === null)
114
- return binding.initializers;
115
- const positions = binding.initializers.map(({ node }) => directInitializerPosition(node, parents));
116
- if (positions.some((position) => position === null ||
117
- position.body !== mutationPosition.body ||
118
- position.index >= mutationPosition.index))
119
- return binding.initializers;
120
- const latestIndex = positions.reduce((latest, position) => Math.max(latest, position?.index ?? -1), -1);
121
- return binding.initializers.filter((_, index) => positions[index]?.index === latestIndex);
442
+ const iterable = reference.mutation.right;
443
+ // Expand only the loop's yielded-item selector. Enumerating dynamic property
444
+ // selections would multiply paths through shared object aliases.
445
+ const source = [
446
+ reference,
447
+ ...(reference.requiredSources ?? []),
448
+ ...(reference.fallbackSources ?? []),
449
+ ].find((source) => source.node === iterable && source.projection[0] === null);
450
+ if (source === undefined)
451
+ return null;
452
+ const slot = selectedReferenceSlot({ node: iterable, projection: [] }, state);
453
+ const container = slot === undefined ? null : semanticContainer(slot.value);
454
+ if (container?.coverage.status !== "complete")
455
+ return null;
456
+ const select = (candidate, name) => ({
457
+ ...candidate,
458
+ projection: candidate.node === iterable && candidate.projection[0] === null
459
+ ? [name, ...candidate.projection.slice(1)]
460
+ : candidate.projection,
461
+ });
462
+ return container.slots.map((slot) => {
463
+ const { projection } = select(reference, slot.name);
464
+ return {
465
+ ...reference,
466
+ projection,
467
+ path: projection,
468
+ fallbackPath: projection,
469
+ ...(reference.requiredSources === undefined
470
+ ? {}
471
+ : {
472
+ requiredSources: reference.requiredSources.map((source) => select(source, slot.name)),
473
+ }),
474
+ ...(reference.fallbackSources === undefined
475
+ ? {}
476
+ : {
477
+ fallbackSources: reference.fallbackSources.map((source) => select(source, slot.name)),
478
+ }),
479
+ };
480
+ });
122
481
  };
123
- const referencedValues = (node, path) => {
124
- const [key, ...remaining] = path;
482
+ const referencedValues = (node, path, effect, state) => {
483
+ if (effect === "escape" && t.isFunction(node))
484
+ return semanticCallableResultExpressions(node).flatMap(({ node, delegated }) => node === null ? [] : [{ node, path: delegated ? [null] : [] }]);
125
485
  // An initializer owns its slots; only deeper writes can affect shared children.
126
- if (t.isObjectExpression(node))
127
- return path.length < 2
128
- ? []
129
- : node.properties.flatMap((property) => {
130
- if (t.isSpreadElement(property))
131
- return [{ node: property.argument, path }];
132
- if (!t.isObjectProperty(property))
133
- return [];
134
- const name = semanticStaticPropertyKey(property.key, property.computed);
135
- return key === null || name === null || String(key) === name
136
- ? [{ node: property.value, path: remaining }]
137
- : [];
138
- });
139
- if (t.isArrayExpression(node)) {
140
- if (path.length < 2)
486
+ if (t.isObjectExpression(node) || t.isArrayExpression(node)) {
487
+ if (effect === "write" && path.length < 2)
141
488
  return [];
142
- let uncertainIndex = false;
143
- return node.elements.flatMap((element, index) => {
144
- if (element === null)
145
- return [];
146
- if (t.isSpreadElement(element)) {
147
- uncertainIndex = true;
148
- return [{ node: element.argument, path: [null, ...remaining] }];
149
- }
150
- return uncertainIndex || key === null || String(key) === String(index)
151
- ? [{ node: element, path: remaining }]
152
- : [];
153
- });
489
+ return t.isObjectExpression(node)
490
+ ? semanticObjectPropertyReferences(node, path, state)
491
+ : arrayReferencedValues(node, path);
492
+ }
493
+ if (t.isClass(node)) {
494
+ const [key, ...remaining] = path;
495
+ if (key === undefined)
496
+ return [];
497
+ // Replacing or deleting the getter's property does not use the value it
498
+ // would return. Only a deeper path can mutate the returned object.
499
+ if (effect === "write" && remaining.length === 0)
500
+ return [];
501
+ return semanticClassPropertyReferences({ owner: node, kind: "static" }, [key, ...remaining], state);
502
+ }
503
+ if (t.isNewExpression(node)) {
504
+ const [key, ...remaining] = path;
505
+ if (key === undefined)
506
+ return [];
507
+ if (effect === "write" && remaining.length === 0)
508
+ return [];
509
+ return semanticClassCandidates(node.callee, state).flatMap((klass) => semanticClassPropertyReferences({ owner: klass, kind: "instance" }, [key, ...remaining], state));
510
+ }
511
+ if (t.isAssignmentExpression(node))
512
+ return node.operator === "||=" || node.operator === "??="
513
+ ? [
514
+ { node: node.left, path },
515
+ { node: node.right, path },
516
+ ]
517
+ : [{ node: node.right, path }];
518
+ if (t.isAwaitExpression(node))
519
+ return [{ node: node.argument, path }];
520
+ if (t.isSequenceExpression(node)) {
521
+ const last = node.expressions.at(-1);
522
+ return last === undefined ? [] : [{ node: last, path }];
154
523
  }
155
- if (t.isTSAsExpression(node) ||
156
- t.isTSTypeAssertion(node) ||
157
- t.isTSSatisfiesExpression(node) ||
158
- t.isTSNonNullExpression(node))
159
- return [{ node: node.expression, path }];
160
524
  if (t.isConditionalExpression(node))
161
525
  return [
162
526
  { node: node.consequent, path },
@@ -167,7 +531,281 @@ const referencedValues = (node, path) => {
167
531
  { node: node.left, path },
168
532
  { node: node.right, path },
169
533
  ];
170
- if (t.isAssignmentExpression(node, { operator: "&&=" }))
171
- return [{ node: node.right, path }];
172
534
  return [];
173
535
  };
536
+ const observableMutationPaths = (state) => {
537
+ const bindingNodes = new Map();
538
+ const expressions = new WeakMap();
539
+ const pendingExpressions = [];
540
+ const pending = [];
541
+ const queued = new Set();
542
+ const schedule = (node) => {
543
+ if (queued.has(node))
544
+ return;
545
+ queued.add(node);
546
+ pending.push(node);
547
+ };
548
+ const create = (read) =>
549
+ // Most bindings have no object origin or property projection. Materialize
550
+ // each collection only when it contains a fact or relationship.
551
+ read === undefined ? {} : { read };
552
+ const link = (source, target) => {
553
+ if (target.sources?.has(source) === true)
554
+ return;
555
+ (target.sources ??= new Set()).add(source);
556
+ (source.dependents ??= new Set()).add(target);
557
+ schedule(target);
558
+ };
559
+ const expressionNode = (node) => {
560
+ const expression = unwrapJavaScriptExpression(node).node;
561
+ const existing = expressions.get(expression);
562
+ if (existing !== undefined)
563
+ return existing;
564
+ const observer = create();
565
+ expressions.set(expression, observer);
566
+ pendingExpressions.push({ expression, observer });
567
+ return observer;
568
+ };
569
+ const project = (source, path) => {
570
+ let observer = source;
571
+ for (const key of path) {
572
+ const identity = JSON.stringify(key === null || typeof key === "object" ? key : String(key));
573
+ let selected = observer.projections?.get(identity);
574
+ if (selected === undefined) {
575
+ selected = create({ source: observer, key });
576
+ (observer.projections ??= new Map()).set(identity, selected);
577
+ (observer.dependents ??= new Set()).add(selected);
578
+ schedule(selected);
579
+ }
580
+ observer = selected;
581
+ }
582
+ return observer;
583
+ };
584
+ for (const binding of state.bindingsById.values())
585
+ bindingNodes.set(binding.bindingId, create());
586
+ for (const binding of state.bindingsById.values()) {
587
+ const observer = bindingNodes.get(binding.bindingId);
588
+ if (observer === undefined)
589
+ continue;
590
+ for (const initializer of binding.initializers) {
591
+ const expression = unwrapJavaScriptExpression(initializer.node).node;
592
+ // Preserve member paths through class values and local instances so
593
+ // getter-result aliases can be resolved at the accessor boundary.
594
+ if (t.isClass(expression) || t.isNewExpression(expression))
595
+ (observer.origins ??= new Set()).add("opaque");
596
+ link(project(expressionNode(initializer.node), initializer.projection), observer);
597
+ }
598
+ // Preserve exact paths where copies, defaults or iteration need their
599
+ // reference-specific projections; an opaque origin prevents pruning.
600
+ if (binding.referenceInitializers.length > 0)
601
+ (observer.origins ??= new Set()).add("opaque");
602
+ for (const initializer of binding.referenceInitializers) {
603
+ for (const source of [
604
+ initializer,
605
+ ...(initializer.requiredSources ?? []),
606
+ ...(initializer.fallbackSources ?? []),
607
+ ])
608
+ link(expressionNode(source.node), observer);
609
+ }
610
+ }
611
+ const settle = () => {
612
+ while (pendingExpressions.length > 0 || pending.length > 0) {
613
+ while (pendingExpressions.length > 0) {
614
+ const selected = pendingExpressions.pop();
615
+ if (selected === undefined)
616
+ break;
617
+ const { expression, observer } = selected;
618
+ if (t.isObjectExpression(expression) || t.isArrayExpression(expression))
619
+ (observer.origins ??= new Set()).add(expression);
620
+ else if (t.isIdentifier(expression)) {
621
+ const binding = resolveSemanticBindingState(state, expression, expression.name);
622
+ if (binding !== undefined) {
623
+ const origin = bindingNodes.get(binding.bindingId);
624
+ if (origin !== undefined)
625
+ link(origin, observer);
626
+ }
627
+ else if (expression.name === "Array")
628
+ (observer.origins ??= new Set()).add("array");
629
+ else if (["globalThis", "global", "window", "self"].includes(expression.name))
630
+ (observer.origins ??= new Set()).add("ambient");
631
+ }
632
+ else if (t.isMemberExpression(expression) ||
633
+ t.isOptionalMemberExpression(expression))
634
+ link(project(expressionNode(expression.object), [
635
+ semanticStaticPropertyKey(expression.property, expression.computed),
636
+ ]), observer);
637
+ else
638
+ for (const reference of referencedValues(expression, [], "escape", state))
639
+ link(project(expressionNode(reference.node), reference.path), observer);
640
+ schedule(observer);
641
+ }
642
+ const observer = pending.pop();
643
+ if (observer === undefined)
644
+ continue;
645
+ queued.delete(observer);
646
+ let changed = false;
647
+ const add = (origin) => {
648
+ if (observer.origins?.has(origin) === true)
649
+ return;
650
+ (observer.origins ??= new Set()).add(origin);
651
+ changed = true;
652
+ };
653
+ for (const source of observer.sources ?? [])
654
+ for (const origin of source.origins ?? [])
655
+ add(origin);
656
+ if (observer.read !== undefined) {
657
+ const { source, key } = observer.read;
658
+ if (key === null || typeof key === "object") {
659
+ // Dynamic keys and copied-slot masks retain their original paths.
660
+ // Enumerating their exclusion combinations would recreate the growth
661
+ // that the mutation collector's selection union already prevents.
662
+ if ((source.origins?.size ?? 0) > 0)
663
+ add("opaque");
664
+ }
665
+ else
666
+ for (const origin of source.origins ?? []) {
667
+ if (typeof origin === "string") {
668
+ if (origin === "array-prototype" || origin === "opaque")
669
+ add(origin);
670
+ else if (origin === "ambient" &&
671
+ semanticPropertyPathKeyMatches(key, "Array"))
672
+ add("array");
673
+ else if (origin === "array" &&
674
+ semanticPropertyPathKeyMatches(key, "prototype"))
675
+ add("array-prototype");
676
+ }
677
+ else {
678
+ for (const reference of referencedValues(origin, [key], "escape", state)) {
679
+ link(project(expressionNode(reference.node), reference.path), observer);
680
+ if (reference.iterableFallbackPath !== undefined)
681
+ link(project(expressionNode(reference.node), reference.iterableFallbackPath), observer);
682
+ }
683
+ }
684
+ }
685
+ }
686
+ if (changed)
687
+ for (const dependent of observer.dependents ?? [])
688
+ schedule(dependent);
689
+ }
690
+ };
691
+ settle();
692
+ return (bindingId, path, effect) => {
693
+ let observer = bindingNodes.get(bindingId);
694
+ if (observer === undefined)
695
+ return path;
696
+ if (path.some((key) => key !== null && typeof key === "object"))
697
+ return path;
698
+ if (effect === "escape") {
699
+ observer = project(observer, path);
700
+ settle();
701
+ return (observer.origins?.size ?? 0) === 0 ? null : path;
702
+ }
703
+ if ((observer.origins?.size ?? 0) === 0)
704
+ return path.length === 0 ? path : [null];
705
+ for (let offset = 0; offset < path.length; offset++) {
706
+ const key = path[offset];
707
+ if (key === undefined)
708
+ break;
709
+ observer = project(observer, [key]);
710
+ settle();
711
+ if ((observer.origins?.size ?? 0) === 0 && offset + 1 < path.length)
712
+ return [...path.slice(0, offset + 1), null];
713
+ }
714
+ return path;
715
+ };
716
+ };
717
+ const arrayReferencedValues = (node, path) => {
718
+ const [key, ...remaining] = path;
719
+ const selected = key ?? null;
720
+ const selectedIndex = typeof selected === "object" ? null : semanticArrayIndex(selected);
721
+ if (typeof selected !== "object" && selectedIndex === null)
722
+ return [];
723
+ const references = [];
724
+ let minimumIndex = 0;
725
+ let uncertainIndex = false;
726
+ for (const element of node.elements) {
727
+ if (t.isSpreadElement(element)) {
728
+ if (selectedIndex === null || selectedIndex >= minimumIndex) {
729
+ let sourceKey = null;
730
+ if (!uncertainIndex) {
731
+ if (selectedIndex !== null)
732
+ sourceKey = selectedIndex - minimumIndex;
733
+ else if (selected !== null && typeof selected === "object")
734
+ sourceKey = {
735
+ excludedKeys: selected.excludedKeys.flatMap((name) => {
736
+ const index = semanticArrayIndex(name);
737
+ return index === null || index < minimumIndex
738
+ ? []
739
+ : [String(index - minimumIndex)];
740
+ }),
741
+ startIndex: Math.max(0, (selected.startIndex ?? 0) - minimumIndex),
742
+ };
743
+ }
744
+ references.push({
745
+ node: element.argument,
746
+ path: [sourceKey, ...remaining],
747
+ iterableFallbackPath: [],
748
+ });
749
+ }
750
+ uncertainIndex = true;
751
+ continue;
752
+ }
753
+ if (element !== null &&
754
+ (uncertainIndex
755
+ ? selectedIndex === null || selectedIndex >= minimumIndex
756
+ : semanticPropertyPathKeyMatches(selected, String(minimumIndex))))
757
+ references.push({ node: element, path: remaining });
758
+ minimumIndex++;
759
+ }
760
+ return references;
761
+ };
762
+ const copiedReferencePath = (initializer, path, effect) => {
763
+ const offset = initializer.copyProjectionOffset;
764
+ if (offset === undefined)
765
+ return [...initializer.projection, ...path];
766
+ const copiedPath = [...initializer.projection.slice(offset + 1), ...path];
767
+ if (effect === "write" && copiedPath.length < 2)
768
+ return null;
769
+ let [key, ...remaining] = copiedPath;
770
+ if (initializer.copyKind === "array-rest") {
771
+ const startIndex = initializer.copyStartIndex ?? 0;
772
+ if (key === undefined || key === null)
773
+ key = { excludedKeys: [], startIndex };
774
+ else if (typeof key === "object")
775
+ key = {
776
+ excludedKeys: key.excludedKeys.flatMap((name) => {
777
+ const index = semanticArrayIndex(name);
778
+ return index === null ? [] : [String(index + startIndex)];
779
+ }),
780
+ startIndex: (key.startIndex ?? 0) + startIndex,
781
+ };
782
+ else {
783
+ const index = semanticArrayIndex(key);
784
+ if (index === null)
785
+ return null;
786
+ key = index + startIndex;
787
+ }
788
+ }
789
+ else {
790
+ const excludedKeys = initializer.copyExcludedKeys ?? [];
791
+ if (key === undefined || key === null)
792
+ key = { excludedKeys };
793
+ else if (typeof key === "object")
794
+ key = {
795
+ ...key,
796
+ excludedKeys: [...new Set([...key.excludedKeys, ...excludedKeys])].sort(compareUnicodeCodePoints),
797
+ };
798
+ else if (excludedKeys.includes(String(key)))
799
+ return null;
800
+ }
801
+ return [...initializer.projection.slice(0, offset), key, ...remaining];
802
+ };
803
+ const selectedReferenceSlot = (source, state, capturePoint) => {
804
+ const path = [];
805
+ for (const key of source.projection) {
806
+ if (key === null || typeof key === "object")
807
+ return undefined;
808
+ path.push(String(key));
809
+ }
810
+ return semanticSlotAtPath(evaluateSemanticExpression(source.node, state, capturePoint), path);
811
+ };