projscan 4.6.0 → 4.8.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 (415) hide show
  1. package/README.md +25 -12
  2. package/dist/cli/_shared.js +12 -44
  3. package/dist/cli/_shared.js.map +1 -1
  4. package/dist/cli/changedOnly.d.ts +16 -0
  5. package/dist/cli/changedOnly.js +28 -0
  6. package/dist/cli/changedOnly.js.map +1 -0
  7. package/dist/cli/commands/start.js +5 -28
  8. package/dist/cli/commands/start.js.map +1 -1
  9. package/dist/cli/commands/startOptionsRegistration.d.ts +2 -0
  10. package/dist/cli/commands/startOptionsRegistration.js +29 -0
  11. package/dist/cli/commands/startOptionsRegistration.js.map +1 -0
  12. package/dist/cli/formatOptions.d.ts +4 -0
  13. package/dist/cli/formatOptions.js +30 -0
  14. package/dist/cli/formatOptions.js.map +1 -0
  15. package/dist/core/agentBrief.js +6 -1
  16. package/dist/core/agentBrief.js.map +1 -1
  17. package/dist/core/ast.d.ts +2 -17
  18. package/dist/core/ast.js +4 -33
  19. package/dist/core/ast.js.map +1 -1
  20. package/dist/core/astBodySignals.js +2 -3
  21. package/dist/core/astBodySignals.js.map +1 -1
  22. package/dist/core/astMembers.d.ts +1 -0
  23. package/dist/core/astMembers.js +38 -9
  24. package/dist/core/astMembers.js.map +1 -1
  25. package/dist/core/astResult.d.ts +20 -0
  26. package/dist/core/astResult.js +39 -0
  27. package/dist/core/astResult.js.map +1 -0
  28. package/dist/core/bugHunt.js +2 -142
  29. package/dist/core/bugHunt.js.map +1 -1
  30. package/dist/core/bugHuntHotspotFindings.d.ts +2 -0
  31. package/dist/core/bugHuntHotspotFindings.js +68 -0
  32. package/dist/core/bugHuntHotspotFindings.js.map +1 -0
  33. package/dist/core/bugHuntPreflightFindings.d.ts +3 -0
  34. package/dist/core/bugHuntPreflightFindings.js +115 -0
  35. package/dist/core/bugHuntPreflightFindings.js.map +1 -0
  36. package/dist/core/codeGraph.d.ts +2 -24
  37. package/dist/core/codeGraph.js +8 -119
  38. package/dist/core/codeGraph.js.map +1 -1
  39. package/dist/core/codeGraphAdapterContexts.d.ts +8 -0
  40. package/dist/core/codeGraphAdapterContexts.js +14 -0
  41. package/dist/core/codeGraphAdapterContexts.js.map +1 -0
  42. package/dist/core/codeGraphFileSelection.d.ts +7 -0
  43. package/dist/core/codeGraphFileSelection.js +19 -0
  44. package/dist/core/codeGraphFileSelection.js.map +1 -0
  45. package/dist/core/codeGraphIncremental.d.ts +17 -0
  46. package/dist/core/codeGraphIncremental.js +64 -0
  47. package/dist/core/codeGraphIncremental.js.map +1 -0
  48. package/dist/core/codeGraphQueries.d.ts +9 -0
  49. package/dist/core/codeGraphQueries.js +25 -0
  50. package/dist/core/codeGraphQueries.js.map +1 -0
  51. package/dist/core/collisionDetector.d.ts +1 -0
  52. package/dist/core/collisionDetector.js +3 -0
  53. package/dist/core/collisionDetector.js.map +1 -1
  54. package/dist/core/coordination.js +23 -5
  55. package/dist/core/coordination.js.map +1 -1
  56. package/dist/core/coordinationEvidence.d.ts +1 -0
  57. package/dist/core/coordinationEvidence.js.map +1 -1
  58. package/dist/core/dataflow.js +3 -338
  59. package/dist/core/dataflow.js.map +1 -1
  60. package/dist/core/dataflowDatabaseSinks.d.ts +8 -0
  61. package/dist/core/dataflowDatabaseSinks.js +78 -0
  62. package/dist/core/dataflowDatabaseSinks.js.map +1 -0
  63. package/dist/core/dataflowRiskAssembly.d.ts +11 -0
  64. package/dist/core/dataflowRiskAssembly.js +117 -0
  65. package/dist/core/dataflowRiskAssembly.js.map +1 -0
  66. package/dist/core/dataflowTraversal.d.ts +25 -0
  67. package/dist/core/dataflowTraversal.js +200 -0
  68. package/dist/core/dataflowTraversal.js.map +1 -0
  69. package/dist/core/fileInspectionReport.d.ts +13 -0
  70. package/dist/core/fileInspectionReport.js +49 -0
  71. package/dist/core/fileInspectionReport.js.map +1 -0
  72. package/dist/core/fileInspector.d.ts +3 -11
  73. package/dist/core/fileInspector.js +2 -46
  74. package/dist/core/fileInspector.js.map +1 -1
  75. package/dist/core/fixSuggest.d.ts +1 -9
  76. package/dist/core/fixSuggest.js +2 -58
  77. package/dist/core/fixSuggest.js.map +1 -1
  78. package/dist/core/fixSuggestDependencyNames.d.ts +1 -0
  79. package/dist/core/fixSuggestDependencyNames.js +9 -0
  80. package/dist/core/fixSuggestDependencyNames.js.map +1 -0
  81. package/dist/core/fixSuggestPreview.d.ts +10 -0
  82. package/dist/core/fixSuggestPreview.js +87 -0
  83. package/dist/core/fixSuggestPreview.js.map +1 -0
  84. package/dist/core/frameworkExpressSources.js +6 -31
  85. package/dist/core/frameworkExpressSources.js.map +1 -1
  86. package/dist/core/frameworkFastifySources.js +5 -22
  87. package/dist/core/frameworkFastifySources.js.map +1 -1
  88. package/dist/core/frameworkHonoSources.js +12 -24
  89. package/dist/core/frameworkHonoSources.js.map +1 -1
  90. package/dist/core/frameworkKoaSources.js +5 -24
  91. package/dist/core/frameworkKoaSources.js.map +1 -1
  92. package/dist/core/frameworkNextRouteSources.d.ts +6 -1
  93. package/dist/core/frameworkNextRouteSources.js +31 -1
  94. package/dist/core/frameworkNextRouteSources.js.map +1 -1
  95. package/dist/core/frameworkRemixSources.d.ts +2 -0
  96. package/dist/core/frameworkRemixSources.js +63 -0
  97. package/dist/core/frameworkRemixSources.js.map +1 -0
  98. package/dist/core/frameworkSourceContext.d.ts +15 -0
  99. package/dist/core/frameworkSourceContext.js +2 -0
  100. package/dist/core/frameworkSourceContext.js.map +1 -0
  101. package/dist/core/frameworkSourceMatching.d.ts +6 -0
  102. package/dist/core/frameworkSourceMatching.js +29 -0
  103. package/dist/core/frameworkSourceMatching.js.map +1 -0
  104. package/dist/core/frameworkSourceResolvers.d.ts +2 -0
  105. package/dist/core/frameworkSourceResolvers.js +45 -0
  106. package/dist/core/frameworkSourceResolvers.js.map +1 -0
  107. package/dist/core/frameworkSources.d.ts +3 -3
  108. package/dist/core/frameworkSources.js +17 -15
  109. package/dist/core/frameworkSources.js.map +1 -1
  110. package/dist/core/frameworkSvelteKitSources.d.ts +2 -0
  111. package/dist/core/frameworkSvelteKitSources.js +118 -0
  112. package/dist/core/frameworkSvelteKitSources.js.map +1 -0
  113. package/dist/core/intentRouter.d.ts +4 -14
  114. package/dist/core/intentRouter.js +2 -33
  115. package/dist/core/intentRouter.js.map +1 -1
  116. package/dist/core/intentRouterCatalog.js +49 -0
  117. package/dist/core/intentRouterCatalog.js.map +1 -1
  118. package/dist/core/intentRouterKeywordToolGuards.js +5 -0
  119. package/dist/core/intentRouterKeywordToolGuards.js.map +1 -1
  120. package/dist/core/intentRouterKeywordWeights.js +36 -0
  121. package/dist/core/intentRouterKeywordWeights.js.map +1 -1
  122. package/dist/core/intentRouterReleaseSignals.js +104 -39
  123. package/dist/core/intentRouterReleaseSignals.js.map +1 -1
  124. package/dist/core/intentRouterResolution.d.ts +3 -0
  125. package/dist/core/intentRouterResolution.js +11 -0
  126. package/dist/core/intentRouterResolution.js.map +1 -0
  127. package/dist/core/intentRouterResult.d.ts +16 -0
  128. package/dist/core/intentRouterResult.js +34 -0
  129. package/dist/core/intentRouterResult.js.map +1 -0
  130. package/dist/core/intentRouterWorkSignals.js +18 -0
  131. package/dist/core/intentRouterWorkSignals.js.map +1 -1
  132. package/dist/core/languages/pythonLockfiles.d.ts +4 -0
  133. package/dist/core/languages/pythonLockfiles.js +6 -2
  134. package/dist/core/languages/pythonLockfiles.js.map +1 -1
  135. package/dist/core/languages/pythonManifests.js +11 -24
  136. package/dist/core/languages/pythonManifests.js.map +1 -1
  137. package/dist/core/languages/pythonPep508.js +1 -1
  138. package/dist/core/languages/pythonPep508.js.map +1 -1
  139. package/dist/core/languages/pythonProjectEvidence.js +4 -4
  140. package/dist/core/languages/pythonProjectEvidence.js.map +1 -1
  141. package/dist/core/languages/pythonPyproject.js +1 -1
  142. package/dist/core/languages/pythonPyproject.js.map +1 -1
  143. package/dist/core/languages/pythonPyprojectEvidence.d.ts +7 -0
  144. package/dist/core/languages/pythonPyprojectEvidence.js +23 -0
  145. package/dist/core/languages/pythonPyprojectEvidence.js.map +1 -0
  146. package/dist/core/languages/pythonRequirements.d.ts +2 -0
  147. package/dist/core/languages/pythonRequirements.js +215 -24
  148. package/dist/core/languages/pythonRequirements.js.map +1 -1
  149. package/dist/core/pluginAnalyzerLoading.d.ts +3 -0
  150. package/dist/core/pluginAnalyzerLoading.js +55 -0
  151. package/dist/core/pluginAnalyzerLoading.js.map +1 -0
  152. package/dist/core/pluginAnalyzerRunning.d.ts +10 -0
  153. package/dist/core/pluginAnalyzerRunning.js +32 -0
  154. package/dist/core/pluginAnalyzerRunning.js.map +1 -0
  155. package/dist/core/pluginIssueValidation.d.ts +2 -0
  156. package/dist/core/pluginIssueValidation.js +22 -0
  157. package/dist/core/pluginIssueValidation.js.map +1 -0
  158. package/dist/core/pluginManifestDiscovery.d.ts +25 -0
  159. package/dist/core/pluginManifestDiscovery.js +80 -0
  160. package/dist/core/pluginManifestDiscovery.js.map +1 -0
  161. package/dist/core/pluginManifestValidation.d.ts +41 -0
  162. package/dist/core/pluginManifestValidation.js +179 -0
  163. package/dist/core/pluginManifestValidation.js.map +1 -0
  164. package/dist/core/pluginModuleLoading.d.ts +8 -0
  165. package/dist/core/pluginModuleLoading.js +91 -0
  166. package/dist/core/pluginModuleLoading.js.map +1 -0
  167. package/dist/core/pluginReporterLoading.d.ts +41 -0
  168. package/dist/core/pluginReporterLoading.js +105 -0
  169. package/dist/core/pluginReporterLoading.js.map +1 -0
  170. package/dist/core/pluginRuntimeTypes.d.ts +20 -0
  171. package/dist/core/pluginRuntimeTypes.js +2 -0
  172. package/dist/core/pluginRuntimeTypes.js.map +1 -0
  173. package/dist/core/plugins.d.ts +11 -126
  174. package/dist/core/plugins.js +13 -478
  175. package/dist/core/plugins.js.map +1 -1
  176. package/dist/core/preflight.d.ts +1 -2
  177. package/dist/core/preflight.js +4 -91
  178. package/dist/core/preflight.js.map +1 -1
  179. package/dist/core/preflightEvidence.js +11 -0
  180. package/dist/core/preflightEvidence.js.map +1 -1
  181. package/dist/core/preflightInputs.d.ts +1 -0
  182. package/dist/core/preflightInputs.js.map +1 -1
  183. package/dist/core/preflightReasons.d.ts +21 -0
  184. package/dist/core/preflightReasons.js +28 -0
  185. package/dist/core/preflightReasons.js.map +1 -0
  186. package/dist/core/preflightReport.d.ts +9 -0
  187. package/dist/core/preflightReport.js +67 -0
  188. package/dist/core/preflightReport.js.map +1 -0
  189. package/dist/core/regressionPlan.d.ts +2 -1
  190. package/dist/core/regressionPlan.js +7 -1
  191. package/dist/core/regressionPlan.js.map +1 -1
  192. package/dist/core/releaseEvidence.js +6 -120
  193. package/dist/core/releaseEvidence.js.map +1 -1
  194. package/dist/core/releaseEvidenceArtifacts.d.ts +3 -0
  195. package/dist/core/releaseEvidenceArtifacts.js +65 -0
  196. package/dist/core/releaseEvidenceArtifacts.js.map +1 -0
  197. package/dist/core/releaseEvidenceVerdict.d.ts +6 -0
  198. package/dist/core/releaseEvidenceVerdict.js +54 -0
  199. package/dist/core/releaseEvidenceVerdict.js.map +1 -0
  200. package/dist/core/reportPathRedaction.d.ts +4 -0
  201. package/dist/core/reportPathRedaction.js +64 -0
  202. package/dist/core/reportPathRedaction.js.map +1 -0
  203. package/dist/core/reportScope.js +2 -163
  204. package/dist/core/reportScope.js.map +1 -1
  205. package/dist/core/reportScopeFiltering.d.ts +9 -0
  206. package/dist/core/reportScopeFiltering.js +102 -0
  207. package/dist/core/reportScopeFiltering.js.map +1 -0
  208. package/dist/core/review.js +2 -47
  209. package/dist/core/review.js.map +1 -1
  210. package/dist/core/reviewChangedReport.d.ts +13 -0
  211. package/dist/core/reviewChangedReport.js +38 -0
  212. package/dist/core/reviewChangedReport.js.map +1 -0
  213. package/dist/core/reviewComputation.d.ts +9 -0
  214. package/dist/core/reviewComputation.js +14 -0
  215. package/dist/core/reviewComputation.js.map +1 -0
  216. package/dist/core/reviewContractChanges.js +22 -8
  217. package/dist/core/reviewContractChanges.js.map +1 -1
  218. package/dist/core/reviewDataflow.js +18 -0
  219. package/dist/core/reviewDataflow.js.map +1 -1
  220. package/dist/core/roadmapCatalog.js +7 -203
  221. package/dist/core/roadmapCatalog.js.map +1 -1
  222. package/dist/core/roadmapCatalogPost44.d.ts +2 -0
  223. package/dist/core/roadmapCatalogPost44.js +205 -0
  224. package/dist/core/roadmapCatalogPost44.js.map +1 -0
  225. package/dist/core/roadmapCatalogTypes.d.ts +6 -0
  226. package/dist/core/roadmapCatalogTypes.js +2 -0
  227. package/dist/core/roadmapCatalogTypes.js.map +1 -0
  228. package/dist/core/searchIndex.d.ts +2 -14
  229. package/dist/core/searchIndex.js +4 -227
  230. package/dist/core/searchIndex.js.map +1 -1
  231. package/dist/core/searchIndexFiles.d.ts +1 -0
  232. package/dist/core/searchIndexFiles.js +26 -0
  233. package/dist/core/searchIndexFiles.js.map +1 -0
  234. package/dist/core/searchIndexText.d.ts +15 -0
  235. package/dist/core/searchIndexText.js +204 -0
  236. package/dist/core/searchIndexText.js.map +1 -0
  237. package/dist/core/start.js +5 -46
  238. package/dist/core/start.js.map +1 -1
  239. package/dist/core/startClaimRouteCriteria.d.ts +7 -0
  240. package/dist/core/startClaimRouteCriteria.js +16 -0
  241. package/dist/core/startClaimRouteCriteria.js.map +1 -0
  242. package/dist/core/startCouplingRouteCriteria.d.ts +2 -0
  243. package/dist/core/startCouplingRouteCriteria.js +13 -0
  244. package/dist/core/startCouplingRouteCriteria.js.map +1 -0
  245. package/dist/core/startDependencyRouteCriteria.d.ts +2 -0
  246. package/dist/core/startDependencyRouteCriteria.js +43 -0
  247. package/dist/core/startDependencyRouteCriteria.js.map +1 -0
  248. package/dist/core/startEvidence.d.ts +1 -1
  249. package/dist/core/startEvidence.js +16 -1
  250. package/dist/core/startEvidence.js.map +1 -1
  251. package/dist/core/startFileRouteCriteria.d.ts +2 -0
  252. package/dist/core/startFileRouteCriteria.js +56 -0
  253. package/dist/core/startFileRouteCriteria.js.map +1 -0
  254. package/dist/core/startFixedRouteCriteria.d.ts +1 -0
  255. package/dist/core/startFixedRouteCriteria.js +90 -0
  256. package/dist/core/startFixedRouteCriteria.js.map +1 -0
  257. package/dist/core/startImpactRouteCriteria.d.ts +7 -0
  258. package/dist/core/startImpactRouteCriteria.js +14 -0
  259. package/dist/core/startImpactRouteCriteria.js.map +1 -0
  260. package/dist/core/startInputs.d.ts +1 -0
  261. package/dist/core/startInputs.js +4 -1
  262. package/dist/core/startInputs.js.map +1 -1
  263. package/dist/core/startIntentTargets.d.ts +1 -0
  264. package/dist/core/startIntentTargets.js +28 -0
  265. package/dist/core/startIntentTargets.js.map +1 -1
  266. package/dist/core/startMissionControl.js +8 -2
  267. package/dist/core/startMissionControl.js.map +1 -1
  268. package/dist/core/startMissionPolicy.js +12 -0
  269. package/dist/core/startMissionPolicy.js.map +1 -1
  270. package/dist/core/startMode.d.ts +1 -0
  271. package/dist/core/startMode.js +10 -2
  272. package/dist/core/startMode.js.map +1 -1
  273. package/dist/core/startPreflightRouteCriteria.d.ts +11 -0
  274. package/dist/core/startPreflightRouteCriteria.js +29 -0
  275. package/dist/core/startPreflightRouteCriteria.js.map +1 -0
  276. package/dist/core/startProductPlanningRouteCriteria.d.ts +8 -0
  277. package/dist/core/startProductPlanningRouteCriteria.js +29 -0
  278. package/dist/core/startProductPlanningRouteCriteria.js.map +1 -0
  279. package/dist/core/startRegressionRouteCriteria.d.ts +3 -0
  280. package/dist/core/startRegressionRouteCriteria.js +62 -0
  281. package/dist/core/startRegressionRouteCriteria.js.map +1 -0
  282. package/dist/core/startReportBuilder.d.ts +1 -0
  283. package/dist/core/startReportBuilder.js +1 -0
  284. package/dist/core/startReportBuilder.js.map +1 -1
  285. package/dist/core/startReportContext.d.ts +23 -0
  286. package/dist/core/startReportContext.js +51 -0
  287. package/dist/core/startReportContext.js.map +1 -0
  288. package/dist/core/startRoadmapPreview.d.ts +2 -0
  289. package/dist/core/startRoadmapPreview.js +31 -0
  290. package/dist/core/startRoadmapPreview.js.map +1 -0
  291. package/dist/core/startRouteActions.js +39 -1
  292. package/dist/core/startRouteActions.js.map +1 -1
  293. package/dist/core/startSuccessCriteria.d.ts +2 -3
  294. package/dist/core/startSuccessCriteria.js +15 -419
  295. package/dist/core/startSuccessCriteria.js.map +1 -1
  296. package/dist/core/startUnderstandRouteCriteria.d.ts +3 -0
  297. package/dist/core/startUnderstandRouteCriteria.js +97 -0
  298. package/dist/core/startUnderstandRouteCriteria.js.map +1 -0
  299. package/dist/core/taint.d.ts +2 -67
  300. package/dist/core/taint.js +41 -164
  301. package/dist/core/taint.js.map +1 -1
  302. package/dist/core/taintIndex.d.ts +20 -0
  303. package/dist/core/taintIndex.js +81 -0
  304. package/dist/core/taintIndex.js.map +1 -0
  305. package/dist/core/taintTraversal.d.ts +8 -0
  306. package/dist/core/taintTraversal.js +113 -0
  307. package/dist/core/taintTraversal.js.map +1 -0
  308. package/dist/core/taintTypes.d.ts +67 -0
  309. package/dist/core/taintTypes.js +2 -0
  310. package/dist/core/taintTypes.js.map +1 -0
  311. package/dist/core/telemetry.d.ts +9 -89
  312. package/dist/core/telemetry.js +35 -387
  313. package/dist/core/telemetry.js.map +1 -1
  314. package/dist/core/telemetryConfig.d.ts +58 -0
  315. package/dist/core/telemetryConfig.js +171 -0
  316. package/dist/core/telemetryConfig.js.map +1 -0
  317. package/dist/core/telemetryEvents.d.ts +57 -0
  318. package/dist/core/telemetryEvents.js +143 -0
  319. package/dist/core/telemetryEvents.js.map +1 -0
  320. package/dist/core/telemetryFlushing.d.ts +10 -0
  321. package/dist/core/telemetryFlushing.js +42 -0
  322. package/dist/core/telemetryFlushing.js.map +1 -0
  323. package/dist/core/telemetryRecording.d.ts +26 -0
  324. package/dist/core/telemetryRecording.js +38 -0
  325. package/dist/core/telemetryRecording.js.map +1 -0
  326. package/dist/core/telemetrySender.d.ts +9 -0
  327. package/dist/core/telemetrySender.js +22 -0
  328. package/dist/core/telemetrySender.js.map +1 -0
  329. package/dist/core/upgradePreviewPython.js +1 -1
  330. package/dist/core/upgradePreviewPython.js.map +1 -1
  331. package/dist/index.d.ts +4 -60
  332. package/dist/index.js +4 -60
  333. package/dist/index.js.map +1 -1
  334. package/dist/mcp/server.js +2 -13
  335. package/dist/mcp/server.js.map +1 -1
  336. package/dist/mcp/serverMessageHandling.d.ts +3 -0
  337. package/dist/mcp/serverMessageHandling.js +16 -0
  338. package/dist/mcp/serverMessageHandling.js.map +1 -0
  339. package/dist/mcp/toolDefinitions.d.ts +3 -0
  340. package/dist/mcp/toolDefinitions.js +15 -0
  341. package/dist/mcp/toolDefinitions.js.map +1 -0
  342. package/dist/mcp/tools.js +2 -13
  343. package/dist/mcp/tools.js.map +1 -1
  344. package/dist/projscan-sbom.cdx.json +6 -6
  345. package/dist/publicAgent.d.ts +22 -0
  346. package/dist/publicAgent.js +23 -0
  347. package/dist/publicAgent.js.map +1 -0
  348. package/dist/publicCore.d.ts +29 -0
  349. package/dist/publicCore.js +30 -0
  350. package/dist/publicCore.js.map +1 -0
  351. package/dist/publicLanguages.d.ts +1 -0
  352. package/dist/publicLanguages.js +2 -0
  353. package/dist/publicLanguages.js.map +1 -0
  354. package/dist/publicMcp.d.ts +8 -0
  355. package/dist/publicMcp.js +9 -0
  356. package/dist/publicMcp.js.map +1 -0
  357. package/dist/reporters/consoleFixReporter.d.ts +3 -0
  358. package/dist/reporters/consoleFixReporter.js +41 -0
  359. package/dist/reporters/consoleFixReporter.js.map +1 -0
  360. package/dist/reporters/consoleReporter.d.ts +1 -3
  361. package/dist/reporters/consoleReporter.js +1 -42
  362. package/dist/reporters/consoleReporter.js.map +1 -1
  363. package/dist/reporters/htmlAnalysisReporter.d.ts +3 -0
  364. package/dist/reporters/htmlAnalysisReporter.js +98 -0
  365. package/dist/reporters/htmlAnalysisReporter.js.map +1 -0
  366. package/dist/reporters/htmlCoverageReporter.d.ts +2 -0
  367. package/dist/reporters/htmlCoverageReporter.js +52 -0
  368. package/dist/reporters/htmlCoverageReporter.js.map +1 -0
  369. package/dist/reporters/htmlImpactReporter.d.ts +2 -0
  370. package/dist/reporters/htmlImpactReporter.js +41 -0
  371. package/dist/reporters/htmlImpactReporter.js.map +1 -0
  372. package/dist/reporters/htmlPrDiffReporter.d.ts +2 -0
  373. package/dist/reporters/htmlPrDiffReporter.js +84 -0
  374. package/dist/reporters/htmlPrDiffReporter.js.map +1 -0
  375. package/dist/reporters/htmlReporter.d.ts +20 -9
  376. package/dist/reporters/htmlReporter.js +7 -365
  377. package/dist/reporters/htmlReporter.js.map +1 -1
  378. package/dist/reporters/htmlReviewReporter.d.ts +2 -0
  379. package/dist/reporters/htmlReviewReporter.js +94 -0
  380. package/dist/reporters/htmlReviewReporter.js.map +1 -0
  381. package/dist/reporters/htmlShared.d.ts +7 -0
  382. package/dist/reporters/htmlShared.js +106 -0
  383. package/dist/reporters/htmlShared.js.map +1 -0
  384. package/dist/tool-manifest.json +2 -2
  385. package/dist/types/preflight.d.ts +19 -0
  386. package/dist/types/start.d.ts +7 -437
  387. package/dist/types/startCommon.d.ts +79 -0
  388. package/dist/types/startCommon.js +2 -0
  389. package/dist/types/startCommon.js.map +1 -0
  390. package/dist/types/startExecution.d.ts +44 -0
  391. package/dist/types/startExecution.js +2 -0
  392. package/dist/types/startExecution.js.map +1 -0
  393. package/dist/types/startMissionControl.d.ts +91 -0
  394. package/dist/types/startMissionControl.js +2 -0
  395. package/dist/types/startMissionControl.js.map +1 -0
  396. package/dist/types/startMissionProof.d.ts +91 -0
  397. package/dist/types/startMissionProof.js +2 -0
  398. package/dist/types/startMissionProof.js.map +1 -0
  399. package/dist/types/startMissionResume.d.ts +100 -0
  400. package/dist/types/startMissionResume.js +2 -0
  401. package/dist/types/startMissionResume.js.map +1 -0
  402. package/dist/types/startMissionReview.d.ts +45 -0
  403. package/dist/types/startMissionReview.js +2 -0
  404. package/dist/types/startMissionReview.js.map +1 -0
  405. package/dist/types/startMissionTooling.d.ts +16 -0
  406. package/dist/types/startMissionTooling.js +2 -0
  407. package/dist/types/startMissionTooling.js.map +1 -0
  408. package/dist/utils/changedFiles.d.ts +1 -0
  409. package/dist/utils/changedFiles.js +7 -4
  410. package/dist/utils/changedFiles.js.map +1 -1
  411. package/docs/GUIDE.md +9 -7
  412. package/docs/ROADMAP.md +18 -7
  413. package/docs/examples/adoption-workflows.md +12 -1
  414. package/docs/examples/swarm-coordination.md +11 -2
  415. package/package.json +1 -1
@@ -1,4 +1,6 @@
1
1
  import type { CodeGraph } from './codeGraph.js';
2
+ import type { TaintConfig, TaintReport } from './taintTypes.js';
3
+ export type { TaintConfig, TaintFlow, TaintReport } from './taintTypes.js';
2
4
  /**
3
5
  * Lightweight taint flow analysis (1.6+).
4
6
  *
@@ -29,75 +31,8 @@ import type { CodeGraph } from './codeGraph.js';
29
31
  * variable-level dataflow, no AST inspection beyond what callSites
30
32
  * already gives us. If this drifts toward "general dataflow" cut it.
31
33
  */
32
- export interface TaintConfig {
33
- /**
34
- * Bare callee names treated as taint sources. Examples:
35
- * "process.env" — environment variables (read sensitive config)
36
- * "req.body" — HTTP request body
37
- * "readFileSync" — disk read (could be user-controlled paths)
38
- *
39
- * Match is by bare name (the rightmost identifier in a member-access
40
- * chain). "process.env.SECRET" → "env"; "req.body.userId" → "body".
41
- * The default list captures the most common JS / Python / Go sources;
42
- * users override via .projscanrc taint.sources.
43
- */
44
- sources: string[];
45
- /**
46
- * Bare callee names treated as taint sinks. Examples:
47
- * "exec" — child_process.exec
48
- * "spawn" — child_process.spawn
49
- * "writeFile" — fs.writeFile
50
- * "query" — raw SQL (db.query("SELECT...${user}"))
51
- * "eval" — JS eval / Python eval / etc.
52
- */
53
- sinks: string[];
54
- }
55
34
  export declare const DEFAULT_TAINT_SOURCES: ReadonlyArray<string>;
56
35
  export declare const DEFAULT_TAINT_SINKS: ReadonlyArray<string>;
57
- export interface TaintFlow {
58
- /** Bare function name where the source was called. */
59
- sourceFn: string;
60
- /** Bare function name where the sink was called. */
61
- sinkFn: string;
62
- /** The source identifier (e.g. "env"). */
63
- source: string;
64
- /** The sink identifier (e.g. "exec"). */
65
- sink: string;
66
- /**
67
- * Sequence of fully-qualified function names from sourceFn to sinkFn,
68
- * inclusive at both ends. Length 1 means the same function reads the
69
- * source and calls the sink (the most direct flow).
70
- */
71
- path: string[];
72
- /** Files touched by the path (in order, deduped). */
73
- files: string[];
74
- }
75
- export interface TaintReport {
76
- available: boolean;
77
- reason?: string;
78
- flowCount: number;
79
- flows: TaintFlow[];
80
- /** The effective sources/sinks list used for this run (after merging defaults + config). */
81
- effectiveSources: string[];
82
- effectiveSinks: string[];
83
- /**
84
- * 1.8+ — true when the BFS hit MAX_DEPTH for at least one source with
85
- * a non-empty frontier still pending. When set, the agent should know
86
- * that flows deeper than MAX_DEPTH may exist but weren't reported.
87
- * Pairs with `truncatedSources` so a follow-up scan can re-target.
88
- */
89
- truncated?: boolean;
90
- /**
91
- * 1.8+ — function names whose BFS exited at MAX_DEPTH with the
92
- * frontier non-empty. Empty when no truncation occurred.
93
- */
94
- truncatedSources?: string[];
95
- /**
96
- * 1.8+ — the depth cap actually used. Surfacing this lets agents
97
- * notice when projscan's defaults shift between releases.
98
- */
99
- maxDepth?: number;
100
- }
101
36
  /**
102
37
  * Compute taint flows over the given code graph. Per-function callSites
103
38
  * are required (1.5+ ships these for every adapter); functions without
@@ -1,5 +1,36 @@
1
- import { FRAMEWORK_REQUEST_SOURCES, frameworkRequestSourceForFunction, } from './frameworkSources.js';
2
- import { isDefaultChildProcessEnvPassthrough, pickSinkHit, pickSourceHit, } from './taintMatching.js';
1
+ import { FRAMEWORK_REQUEST_SOURCES } from './frameworkSources.js';
2
+ import { buildTaintFunctionIndex } from './taintIndex.js';
3
+ import { findTaintFlows } from './taintTraversal.js';
4
+ /**
5
+ * Lightweight taint flow analysis (1.6+).
6
+ *
7
+ * Source-to-sink reachability over the existing per-function call
8
+ * graph. Sources and sinks are *declared* by name (config-driven);
9
+ * anything in between is treated as a function that might propagate
10
+ * taint. We do NOT do general dataflow — we only ask "does some
11
+ * call chain reach from a function that calls a source to a function
12
+ * that calls a sink?"
13
+ *
14
+ * That heuristic catches the common case: a route handler reads
15
+ * `process.env.SECRET` (source) and somewhere downstream it ends up
16
+ * in `child_process.spawn` (sink). It misses any flow that goes
17
+ * through code we can't see (eval'd strings, plugin loaders), and it
18
+ * over-reports when functions read sources but launder them safely
19
+ * before reaching sinks. Both are documented limitations.
20
+ *
21
+ * Legacy taint algorithm gap (1.6+): the "bridge-helper" pattern is missed —
22
+ * `function bridge() { const v = getSecret(); runDangerous(v); }` where
23
+ * `getSecret` reads the source and `runDangerous` is the sink. The BFS
24
+ * walks DOWN from source-fns, but `bridge` has neither source nor sink
25
+ * directly; both are its callees. 3.0's `computeDataflow` /
26
+ * `projscan_dataflow` runs that second algorithm and review surfaces it
27
+ * as `newDataflowRisks`. Keep this legacy function as the compatibility
28
+ * source-to-sink reachability report.
29
+ *
30
+ * Strict scope discipline (per ROADMAP 1.6 guardrail): no CFG, no
31
+ * variable-level dataflow, no AST inspection beyond what callSites
32
+ * already gives us. If this drifts toward "general dataflow" cut it.
33
+ */
3
34
  export const DEFAULT_TAINT_SOURCES = [
4
35
  'env', // process.env.X
5
36
  'argv', // process.argv
@@ -55,50 +86,8 @@ export function computeTaint(graph, config) {
55
86
  const sinks = new Set([...DEFAULT_TAINT_SINKS, ...config.sinks]);
56
87
  const customSources = new Set(config.sources);
57
88
  const customSinks = new Set(config.sinks);
58
- const fnByQual = new Map();
59
- const fnsByBareName = new Map();
60
- let totalCallSites = 0;
61
- for (const [file, gf] of graph.files) {
62
- if (!gf.functions)
63
- continue;
64
- for (const fn of gf.functions) {
65
- const callees = fn.callSites ?? [];
66
- const directCallSites = fn.directCallSites ?? [];
67
- const memberCallSites = fn.memberCallSites ?? [];
68
- const memberReferences = fn.memberReferences ?? [];
69
- const memberAliases = fn.memberAliases ?? [];
70
- const references = fn.references ?? [];
71
- totalCallSites += callees.length;
72
- // Default sources mostly match property/reference reads; custom sources
73
- // may still be call-shaped. Sinks are call-shaped, so callSites only.
74
- const sourceHit = frameworkRequestSourceForFunction(file, fn.name, memberCallSites, memberReferences, fn.parameters ?? [], sources, references, fn.contextualCallSite, gf.imports) ?? pickSourceHit(callees, references, sources, customSources);
75
- const sinkHit = pickSinkHit(callees, directCallSites, memberCallSites, memberAliases, sinks, customSinks, file, gf);
76
- const hasSource = sourceHit !== null &&
77
- !isDefaultChildProcessEnvPassthrough(sourceHit, sinkHit, memberReferences, customSources, customSinks);
78
- const hasSink = sinkHit !== null;
79
- const node = {
80
- id: `${file}::${fn.name}@${fn.line}`,
81
- qualName: fn.name,
82
- bareName: bareName(fn.name),
83
- file,
84
- callees,
85
- references,
86
- memberReferences,
87
- sourceHit,
88
- sinkHit,
89
- hasSource,
90
- hasSink,
91
- };
92
- fnByQual.set(node.id, node);
93
- let list = fnsByBareName.get(node.bareName);
94
- if (!list) {
95
- list = [];
96
- fnsByBareName.set(node.bareName, list);
97
- }
98
- list.push(node);
99
- }
100
- }
101
- if (fnByQual.size === 0 || totalCallSites === 0) {
89
+ const index = buildTaintFunctionIndex(graph, sources, sinks, customSources, customSinks);
90
+ if (index.fnByQual.size === 0 || index.totalCallSites === 0) {
102
91
  return {
103
92
  available: false,
104
93
  reason: 'No functions with callSites in the graph. Taint requires per-function callSites (1.5+).',
@@ -108,128 +97,16 @@ export function computeTaint(graph, config) {
108
97
  effectiveSinks: [...sinks],
109
98
  };
110
99
  }
111
- const flows = [];
112
- const seen = new Set(); // dedupe key: sourceFnId::sinkFnId
113
- // 1.8+ — track which source functions hit MAX_DEPTH with frontier
114
- // still non-empty. The agent gets these in `truncatedSources` so it
115
- // knows where the analysis was clipped.
116
- const truncatedSources = [];
117
- // 1.8+ — raised from 8 → 12. The original 8 was a conservative pick
118
- // when the algorithm was new; six months of dogfood data show real
119
- // user repos averaging 10–11 hops between an HTTP handler and a
120
- // shell-exec sink. 12 catches those without exploding fan-out
121
- // memory in the BFS frontier.
122
- const MAX_DEPTH = 12;
123
- // 1.10+ — per-step frontier cap. MAX_DEPTH bounds path length, but
124
- // wide-fan-out graphs (Java/TS with prevalent get/set/toString bare-name
125
- // collisions) can balloon the frontier exponentially: each step
126
- // resolves every bare-name callee to every same-named function in the
127
- // graph. Once a single step would push past this cap, we abort the
128
- // remaining BFS for this source and surface it in `truncatedSources`,
129
- // matching how MAX_DEPTH truncation is reported.
130
- const MAX_FRONTIER_PER_STEP = 5000;
131
- for (const sourceFn of fnByQual.values()) {
132
- if (!sourceFn.hasSource)
133
- continue;
134
- // Same-function shortcut.
135
- if (sourceFn.hasSink) {
136
- const key = `${sourceFn.id}::${sourceFn.id}`;
137
- if (!seen.has(key)) {
138
- seen.add(key);
139
- flows.push({
140
- sourceFn: sourceFn.qualName,
141
- sinkFn: sourceFn.qualName,
142
- source: sourceFn.sourceHit,
143
- sink: sourceFn.sinkHit,
144
- path: [sourceFn.qualName],
145
- files: [sourceFn.file],
146
- });
147
- }
148
- }
149
- // BFS through callees.
150
- const visited = new Set([sourceFn.id]);
151
- let frontier = [{ node: sourceFn, path: [sourceFn] }];
152
- let depth = 0;
153
- let frontierCapped = false;
154
- while (frontier.length > 0 && depth < MAX_DEPTH) {
155
- depth += 1;
156
- const next = [];
157
- let aborted = false;
158
- for (const entry of frontier) {
159
- if (aborted)
160
- break;
161
- for (const calleeName of entry.node.callees) {
162
- const candidates = fnsByBareName.get(calleeName) ?? [];
163
- for (const candidate of candidates) {
164
- if (visited.has(candidate.id))
165
- continue;
166
- visited.add(candidate.id);
167
- const newPath = [...entry.path, candidate];
168
- if (candidate.hasSink) {
169
- const flowKey = `${sourceFn.id}::${candidate.id}`;
170
- if (!seen.has(flowKey)) {
171
- seen.add(flowKey);
172
- const filesInPath = [];
173
- for (const n of newPath) {
174
- if (filesInPath[filesInPath.length - 1] !== n.file)
175
- filesInPath.push(n.file);
176
- }
177
- flows.push({
178
- sourceFn: sourceFn.qualName,
179
- sinkFn: candidate.qualName,
180
- source: sourceFn.sourceHit,
181
- sink: candidate.sinkHit,
182
- path: newPath.map((n) => n.qualName),
183
- files: filesInPath,
184
- });
185
- }
186
- // Don't continue past a sink — the flow is reported.
187
- continue;
188
- }
189
- next.push({ node: candidate, path: newPath });
190
- if (next.length >= MAX_FRONTIER_PER_STEP) {
191
- // 1.10+ — per-step frontier cap reached. Abort this source's
192
- // BFS and surface it as truncated. Continuing would just
193
- // multiply: each entry in `next` will spawn its own bare-name
194
- // resolutions on the following step.
195
- frontierCapped = true;
196
- aborted = true;
197
- break;
198
- }
199
- }
200
- if (aborted)
201
- break;
202
- }
203
- }
204
- frontier = next;
205
- }
206
- // If the BFS exited because of MAX_DEPTH or the per-step frontier cap
207
- // (not because the frontier emptied), record the source so the caller
208
- // knows flows beyond that point weren't explored.
209
- if (frontier.length > 0 || frontierCapped) {
210
- truncatedSources.push(sourceFn.qualName);
211
- }
212
- }
213
- flows.sort((a, b) => {
214
- if (a.sourceFn !== b.sourceFn)
215
- return a.sourceFn.localeCompare(b.sourceFn);
216
- return a.sinkFn.localeCompare(b.sinkFn);
217
- });
100
+ const traversal = findTaintFlows(index);
218
101
  return {
219
102
  available: true,
220
- flowCount: flows.length,
221
- flows,
103
+ flowCount: traversal.flows.length,
104
+ flows: traversal.flows,
222
105
  effectiveSources: [...sources].sort(),
223
106
  effectiveSinks: [...sinks].sort(),
224
- truncated: truncatedSources.length > 0,
225
- truncatedSources: [...new Set(truncatedSources)].sort(),
226
- maxDepth: MAX_DEPTH,
107
+ truncated: traversal.truncatedSources.length > 0,
108
+ truncatedSources: traversal.truncatedSources,
109
+ maxDepth: traversal.maxDepth,
227
110
  };
228
111
  }
229
- function bareName(qualified) {
230
- const dot = qualified.lastIndexOf('.');
231
- if (dot < 0)
232
- return qualified;
233
- return qualified.slice(dot + 1);
234
- }
235
112
  //# sourceMappingURL=taint.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"taint.js","sourceRoot":"","sources":["../../src/core/taint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"taint.js","sourceRoot":"","sources":["../../src/core/taint.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAKrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAA0B;IAC1D,KAAK,EAAE,gBAAgB;IACvB,MAAM,EAAE,eAAe;IACvB,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,4EAA4E;IACrF,QAAQ,EAAE,aAAa;IACvB,SAAS,EAAE,cAAc;IACzB,SAAS,EAAE,cAAc;IACzB,UAAU,EAAE,wBAAwB;IACpC,cAAc;IACd,OAAO,EAAE,gBAAgB;IACzB,UAAU,EAAE,wBAAwB;IACpC,GAAG,yBAAyB;CAC7B,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAA0B;IACxD,MAAM,EAAE,qBAAqB;IAC7B,UAAU;IACV,OAAO,EAAE,sBAAsB;IAC/B,WAAW;IACX,MAAM,EAAE,cAAc;IACtB,UAAU,EAAE,yCAAyC;IACrD,WAAW,EAAE,6BAA6B;IAC1C,eAAe;IACf,QAAQ,EAAE,gCAAgC;IAC1C,QAAQ;IACR,IAAI;IACJ,OAAO,EAAE,uBAAuB;IAChC,SAAS,EAAE,yBAAyB;IACpC,QAAQ,EAAE,sBAAsB;IAChC,WAAW;IACX,YAAY,EAAE,2BAA2B;IACzC,WAAW,EAAE,wDAAwD;IACrE,kFAAkF;CACnF,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,YAAY,CAAC,KAAgB,EAAE,MAAmB;IAChE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,qBAAqB,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACvE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,mBAAmB,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACjE,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,uBAAuB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;IAEzF,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,cAAc,KAAK,CAAC,EAAE,CAAC;QAC5D,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,MAAM,EACJ,yFAAyF;YAC3F,SAAS,EAAE,CAAC;YACZ,KAAK,EAAE,EAAE;YACT,gBAAgB,EAAE,CAAC,GAAG,OAAO,CAAC;YAC9B,cAAc,EAAE,CAAC,GAAG,KAAK,CAAC;SAC3B,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAExC,OAAO;QACL,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;QACjC,KAAK,EAAE,SAAS,CAAC,KAAK;QACtB,gBAAgB,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE;QACrC,cAAc,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE;QACjC,SAAS,EAAE,SAAS,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC;QAChD,gBAAgB,EAAE,SAAS,CAAC,gBAAgB;QAC5C,QAAQ,EAAE,SAAS,CAAC,QAAQ;KAC7B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { CodeGraph } from './codeGraph.js';
2
+ export interface TaintFunctionNode {
3
+ id: string;
4
+ qualName: string;
5
+ bareName: string;
6
+ file: string;
7
+ callees: string[];
8
+ references: string[];
9
+ memberReferences: string[];
10
+ sourceHit: string | null;
11
+ sinkHit: string | null;
12
+ hasSource: boolean;
13
+ hasSink: boolean;
14
+ }
15
+ export interface TaintFunctionIndex {
16
+ fnByQual: Map<string, TaintFunctionNode>;
17
+ fnsByBareName: Map<string, TaintFunctionNode[]>;
18
+ totalCallSites: number;
19
+ }
20
+ export declare function buildTaintFunctionIndex(graph: CodeGraph, sources: Set<string>, sinks: Set<string>, customSources: Set<string>, customSinks: Set<string>): TaintFunctionIndex;
@@ -0,0 +1,81 @@
1
+ import { frameworkRequestSourceForFunction } from './frameworkSources.js';
2
+ import { isDefaultChildProcessEnvPassthrough, pickSinkHit, pickSourceHit, } from './taintMatching.js';
3
+ const EMPTY_STRING_ARRAY = [];
4
+ export function buildTaintFunctionIndex(graph, sources, sinks, customSources, customSinks) {
5
+ const fnByQual = new Map();
6
+ const fnsByBareName = new Map();
7
+ let totalCallSites = 0;
8
+ for (const [file, graphFile] of graph.files) {
9
+ if (!graphFile.functions)
10
+ continue;
11
+ for (const fn of graphFile.functions) {
12
+ const node = buildTaintFunctionNode(file, graphFile, fn, sources, sinks, customSources, customSinks);
13
+ totalCallSites += node.callees.length;
14
+ fnByQual.set(node.id, node);
15
+ appendByBareName(fnsByBareName, node);
16
+ }
17
+ }
18
+ return { fnByQual, fnsByBareName, totalCallSites };
19
+ }
20
+ function buildTaintFunctionNode(file, graphFile, fn, sources, sinks, customSources, customSinks) {
21
+ const callees = optionalArray(fn.callSites);
22
+ const directCallSites = optionalArray(fn.directCallSites);
23
+ const memberCallSites = optionalArray(fn.memberCallSites);
24
+ const memberReferences = optionalArray(fn.memberReferences);
25
+ const memberAliases = optionalArray(fn.memberAliases);
26
+ const references = optionalArray(fn.references);
27
+ const sourceHit = resolveSourceHit(file, graphFile, fn, callees, directCallSites, memberCallSites, memberReferences, references, sources, customSources);
28
+ const sinkHit = resolveSinkHit(file, graphFile, callees, directCallSites, memberCallSites, memberAliases, sinks, customSinks);
29
+ return {
30
+ id: `${file}::${fn.name}@${fn.line}`,
31
+ qualName: fn.name,
32
+ bareName: bareName(fn.name),
33
+ file,
34
+ callees,
35
+ references,
36
+ memberReferences,
37
+ sourceHit,
38
+ sinkHit,
39
+ hasSource: isActiveSourceHit(sourceHit, sinkHit, memberReferences, customSources, customSinks),
40
+ hasSink: sinkHit !== null,
41
+ };
42
+ }
43
+ function resolveSourceHit(file, graphFile, fn, callees, directCallSites, memberCallSites, memberReferences, references, sources, customSources) {
44
+ return (frameworkRequestSourceForFunction({
45
+ file,
46
+ functionName: fn.name,
47
+ memberCallSites,
48
+ memberReferences,
49
+ parameters: fn.parameters ?? [],
50
+ enabledSources: sources,
51
+ references,
52
+ contextualCallSite: fn.contextualCallSite,
53
+ imports: graphFile.imports,
54
+ directCallSites,
55
+ }) ?? pickSourceHit(callees, references, sources, customSources));
56
+ }
57
+ function resolveSinkHit(file, graphFile, callees, directCallSites, memberCallSites, memberAliases, sinks, customSinks) {
58
+ return pickSinkHit(callees, directCallSites, memberCallSites, memberAliases, sinks, customSinks, file, graphFile);
59
+ }
60
+ function isActiveSourceHit(sourceHit, sinkHit, memberReferences, customSources, customSinks) {
61
+ return (sourceHit !== null &&
62
+ !isDefaultChildProcessEnvPassthrough(sourceHit, sinkHit, memberReferences, customSources, customSinks));
63
+ }
64
+ function appendByBareName(fnsByBareName, node) {
65
+ const existing = fnsByBareName.get(node.bareName);
66
+ if (existing) {
67
+ existing.push(node);
68
+ return;
69
+ }
70
+ fnsByBareName.set(node.bareName, [node]);
71
+ }
72
+ function optionalArray(values) {
73
+ return values ?? EMPTY_STRING_ARRAY;
74
+ }
75
+ function bareName(qualified) {
76
+ const dot = qualified.lastIndexOf('.');
77
+ if (dot < 0)
78
+ return qualified;
79
+ return qualified.slice(dot + 1);
80
+ }
81
+ //# sourceMappingURL=taintIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taintIndex.js","sourceRoot":"","sources":["../../src/core/taintIndex.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EACL,mCAAmC,EACnC,WAAW,EACX,aAAa,GACd,MAAM,oBAAoB,CAAC;AAuB5B,MAAM,kBAAkB,GAAa,EAAE,CAAC;AAExC,MAAM,UAAU,uBAAuB,CACrC,KAAgB,EAChB,OAAoB,EACpB,KAAkB,EAClB,aAA0B,EAC1B,WAAwB;IAExB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA6B,CAAC;IACtD,MAAM,aAAa,GAAG,IAAI,GAAG,EAA+B,CAAC;IAC7D,IAAI,cAAc,GAAG,CAAC,CAAC;IAEvB,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC5C,IAAI,CAAC,SAAS,CAAC,SAAS;YAAE,SAAS;QACnC,KAAK,MAAM,EAAE,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,sBAAsB,CACjC,IAAI,EACJ,SAAS,EACT,EAAE,EACF,OAAO,EACP,KAAK,EACL,aAAa,EACb,WAAW,CACZ,CAAC;YACF,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YACtC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAC5B,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC;AACrD,CAAC;AAED,SAAS,sBAAsB,CAC7B,IAAY,EACZ,SAAoB,EACpB,EAAiB,EACjB,OAAoB,EACpB,KAAkB,EAClB,aAA0B,EAC1B,WAAwB;IAExB,MAAM,OAAO,GAAG,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,eAAe,GAAG,aAAa,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC;IAC1D,MAAM,eAAe,GAAG,aAAa,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC;IAC1D,MAAM,gBAAgB,GAAG,aAAa,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;IAC5D,MAAM,aAAa,GAAG,aAAa,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,aAAa,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,gBAAgB,CAChC,IAAI,EACJ,SAAS,EACT,EAAE,EACF,OAAO,EACP,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,OAAO,EACP,aAAa,CACd,CAAC;IACF,MAAM,OAAO,GAAG,cAAc,CAC5B,IAAI,EACJ,SAAS,EACT,OAAO,EACP,eAAe,EACf,eAAe,EACf,aAAa,EACb,KAAK,EACL,WAAW,CACZ,CAAC;IAEF,OAAO;QACL,EAAE,EAAE,GAAG,IAAI,KAAK,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE;QACpC,QAAQ,EAAE,EAAE,CAAC,IAAI;QACjB,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC;QAC3B,IAAI;QACJ,OAAO;QACP,UAAU;QACV,gBAAgB;QAChB,SAAS;QACT,OAAO;QACP,SAAS,EAAE,iBAAiB,CAAC,SAAS,EAAE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,WAAW,CAAC;QAC9F,OAAO,EAAE,OAAO,KAAK,IAAI;KAC1B,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CACvB,IAAY,EACZ,SAAoB,EACpB,EAAiB,EACjB,OAAiB,EACjB,eAAyB,EACzB,eAAyB,EACzB,gBAA0B,EAC1B,UAAoB,EACpB,OAAoB,EACpB,aAA0B;IAE1B,OAAO,CACL,iCAAiC,CAAC;QAChC,IAAI;QACJ,YAAY,EAAE,EAAE,CAAC,IAAI;QACrB,eAAe;QACf,gBAAgB;QAChB,UAAU,EAAE,EAAE,CAAC,UAAU,IAAI,EAAE;QAC/B,cAAc,EAAE,OAAO;QACvB,UAAU;QACV,kBAAkB,EAAE,EAAE,CAAC,kBAAkB;QACzC,OAAO,EAAE,SAAS,CAAC,OAAO;QAC1B,eAAe;KAChB,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,CAAC,CACjE,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CACrB,IAAY,EACZ,SAAoB,EACpB,OAAiB,EACjB,eAAyB,EACzB,eAAyB,EACzB,aAAuB,EACvB,KAAkB,EAClB,WAAwB;IAExB,OAAO,WAAW,CAChB,OAAO,EACP,eAAe,EACf,eAAe,EACf,aAAa,EACb,KAAK,EACL,WAAW,EACX,IAAI,EACJ,SAAS,CACV,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CACxB,SAAwB,EACxB,OAAsB,EACtB,gBAA0B,EAC1B,aAA0B,EAC1B,WAAwB;IAExB,OAAO,CACL,SAAS,KAAK,IAAI;QAClB,CAAC,mCAAmC,CAClC,SAAS,EACT,OAAO,EACP,gBAAgB,EAChB,aAAa,EACb,WAAW,CACZ,CACF,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CACvB,aAA+C,EAC/C,IAAuB;IAEvB,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClD,IAAI,QAAQ,EAAE,CAAC;QACb,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO;IACT,CAAC;IACD,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,aAAa,CAAC,MAA4B;IACjD,OAAO,MAAM,IAAI,kBAAkB,CAAC;AACtC,CAAC;AAED,SAAS,QAAQ,CAAC,SAAiB;IACjC,MAAM,GAAG,GAAG,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,GAAG,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9B,OAAO,SAAS,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { TaintFunctionIndex } from './taintIndex.js';
2
+ import type { TaintFlow } from './taintTypes.js';
3
+ export interface TaintTraversalResult {
4
+ flows: TaintFlow[];
5
+ truncatedSources: string[];
6
+ maxDepth: number;
7
+ }
8
+ export declare function findTaintFlows(index: TaintFunctionIndex): TaintTraversalResult;
@@ -0,0 +1,113 @@
1
+ const MAX_DEPTH = 12;
2
+ const MAX_FRONTIER_PER_STEP = 5000;
3
+ export function findTaintFlows(index) {
4
+ const flows = [];
5
+ const seen = new Set();
6
+ const truncatedSources = [];
7
+ for (const sourceFn of index.fnByQual.values()) {
8
+ if (!sourceFn.hasSource)
9
+ continue;
10
+ recordSameFunctionFlow(sourceFn, flows, seen);
11
+ if (findFlowsFromSource(sourceFn, index, flows, seen)) {
12
+ truncatedSources.push(sourceFn.qualName);
13
+ }
14
+ }
15
+ sortTaintFlows(flows);
16
+ return {
17
+ flows,
18
+ truncatedSources: [...new Set(truncatedSources)].sort(),
19
+ maxDepth: MAX_DEPTH,
20
+ };
21
+ }
22
+ function recordSameFunctionFlow(sourceFn, flows, seen) {
23
+ if (!sourceFn.hasSink)
24
+ return;
25
+ const key = `${sourceFn.id}::${sourceFn.id}`;
26
+ if (seen.has(key))
27
+ return;
28
+ seen.add(key);
29
+ flows.push({
30
+ sourceFn: sourceFn.qualName,
31
+ sinkFn: sourceFn.qualName,
32
+ source: sourceFn.sourceHit,
33
+ sink: sourceFn.sinkHit,
34
+ path: [sourceFn.qualName],
35
+ files: [sourceFn.file],
36
+ });
37
+ }
38
+ function findFlowsFromSource(sourceFn, index, flows, seen) {
39
+ const visited = new Set([sourceFn.id]);
40
+ let frontier = [{ node: sourceFn, path: [sourceFn] }];
41
+ let depth = 0;
42
+ let frontierCapped = false;
43
+ while (frontier.length > 0 && depth < MAX_DEPTH) {
44
+ depth += 1;
45
+ const result = expandFrontier(sourceFn, frontier, index, visited, flows, seen);
46
+ frontier = result.next;
47
+ frontierCapped ||= result.frontierCapped;
48
+ if (result.frontierCapped)
49
+ break;
50
+ }
51
+ return frontier.length > 0 || frontierCapped;
52
+ }
53
+ function expandFrontier(sourceFn, frontier, index, visited, flows, seen) {
54
+ const next = [];
55
+ for (const entry of frontier) {
56
+ if (expandFrontierEntry(sourceFn, entry, index, visited, flows, seen, next)) {
57
+ return { next, frontierCapped: true };
58
+ }
59
+ }
60
+ return { next, frontierCapped: false };
61
+ }
62
+ function expandFrontierEntry(sourceFn, entry, index, visited, flows, seen, next) {
63
+ for (const calleeName of entry.node.callees) {
64
+ const candidates = index.fnsByBareName.get(calleeName) ?? [];
65
+ for (const candidate of candidates) {
66
+ if (addCandidate(sourceFn, entry, candidate, visited, flows, seen, next))
67
+ return true;
68
+ }
69
+ }
70
+ return false;
71
+ }
72
+ function addCandidate(sourceFn, entry, candidate, visited, flows, seen, next) {
73
+ if (visited.has(candidate.id))
74
+ return false;
75
+ visited.add(candidate.id);
76
+ const newPath = [...entry.path, candidate];
77
+ if (candidate.hasSink) {
78
+ recordPathFlow(sourceFn, candidate, newPath, flows, seen);
79
+ return false;
80
+ }
81
+ next.push({ node: candidate, path: newPath });
82
+ return next.length >= MAX_FRONTIER_PER_STEP;
83
+ }
84
+ function recordPathFlow(sourceFn, sinkFn, path, flows, seen) {
85
+ const flowKey = `${sourceFn.id}::${sinkFn.id}`;
86
+ if (seen.has(flowKey))
87
+ return;
88
+ seen.add(flowKey);
89
+ flows.push({
90
+ sourceFn: sourceFn.qualName,
91
+ sinkFn: sinkFn.qualName,
92
+ source: sourceFn.sourceHit,
93
+ sink: sinkFn.sinkHit,
94
+ path: path.map((node) => node.qualName),
95
+ files: filesInPath(path),
96
+ });
97
+ }
98
+ function filesInPath(path) {
99
+ const files = [];
100
+ for (const node of path) {
101
+ if (files[files.length - 1] !== node.file)
102
+ files.push(node.file);
103
+ }
104
+ return files;
105
+ }
106
+ function sortTaintFlows(flows) {
107
+ flows.sort((a, b) => {
108
+ if (a.sourceFn !== b.sourceFn)
109
+ return a.sourceFn.localeCompare(b.sourceFn);
110
+ return a.sinkFn.localeCompare(b.sinkFn);
111
+ });
112
+ }
113
+ //# sourceMappingURL=taintTraversal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taintTraversal.js","sourceRoot":"","sources":["../../src/core/taintTraversal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ export interface TaintConfig {
2
+ /**
3
+ * Bare callee names treated as taint sources. Examples:
4
+ * "process.env" - environment variables (read sensitive config)
5
+ * "req.body" - HTTP request body
6
+ * "readFileSync" - disk read (could be user-controlled paths)
7
+ *
8
+ * Match is by bare name (the rightmost identifier in a member-access
9
+ * chain). "process.env.SECRET" -> "env"; "req.body.userId" -> "body".
10
+ * The default list captures the most common JS / Python / Go sources;
11
+ * users override via .projscanrc taint.sources.
12
+ */
13
+ sources: string[];
14
+ /**
15
+ * Bare callee names treated as taint sinks. Examples:
16
+ * "exec" - child_process.exec
17
+ * "spawn" - child_process.spawn
18
+ * "writeFile" - fs.writeFile
19
+ * "query" - raw SQL (db.query("SELECT...${user}"))
20
+ * "eval" - JS eval / Python eval / etc.
21
+ */
22
+ sinks: string[];
23
+ }
24
+ export interface TaintFlow {
25
+ /** Bare function name where the source was called. */
26
+ sourceFn: string;
27
+ /** Bare function name where the sink was called. */
28
+ sinkFn: string;
29
+ /** The source identifier (e.g. "env"). */
30
+ source: string;
31
+ /** The sink identifier (e.g. "exec"). */
32
+ sink: string;
33
+ /**
34
+ * Sequence of fully-qualified function names from sourceFn to sinkFn,
35
+ * inclusive at both ends. Length 1 means the same function reads the
36
+ * source and calls the sink (the most direct flow).
37
+ */
38
+ path: string[];
39
+ /** Files touched by the path (in order, deduped). */
40
+ files: string[];
41
+ }
42
+ export interface TaintReport {
43
+ available: boolean;
44
+ reason?: string;
45
+ flowCount: number;
46
+ flows: TaintFlow[];
47
+ /** The effective sources/sinks list used for this run (after merging defaults + config). */
48
+ effectiveSources: string[];
49
+ effectiveSinks: string[];
50
+ /**
51
+ * 1.8+ - true when the BFS hit MAX_DEPTH for at least one source with
52
+ * a non-empty frontier still pending. When set, the agent should know
53
+ * that flows deeper than MAX_DEPTH may exist but weren't reported.
54
+ * Pairs with `truncatedSources` so a follow-up scan can re-target.
55
+ */
56
+ truncated?: boolean;
57
+ /**
58
+ * 1.8+ - function names whose BFS exited at MAX_DEPTH with the
59
+ * frontier non-empty. Empty when no truncation occurred.
60
+ */
61
+ truncatedSources?: string[];
62
+ /**
63
+ * 1.8+ - the depth cap actually used. Surfacing this lets agents
64
+ * notice when projscan's defaults shift between releases.
65
+ */
66
+ maxDepth?: number;
67
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=taintTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taintTypes.js","sourceRoot":"","sources":["../../src/core/taintTypes.ts"],"names":[],"mappings":""}