projscan 4.3.1 → 4.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 (677) hide show
  1. package/CONTRIBUTING.md +5 -1
  2. package/PRIVACY.md +1 -0
  3. package/README.md +253 -229
  4. package/THIRD-PARTY-NOTICES.md +31 -31
  5. package/dist/analyzers/architectureCheck.js.map +1 -1
  6. package/dist/analyzers/crossPackageImportCheck.js +3 -2
  7. package/dist/analyzers/crossPackageImportCheck.js.map +1 -1
  8. package/dist/analyzers/deadCodeCheck.js +10 -2
  9. package/dist/analyzers/deadCodeCheck.js.map +1 -1
  10. package/dist/analyzers/dependencyRiskCheck.js +1 -5
  11. package/dist/analyzers/dependencyRiskCheck.js.map +1 -1
  12. package/dist/analyzers/eslintCheck.js +3 -1
  13. package/dist/analyzers/eslintCheck.js.map +1 -1
  14. package/dist/analyzers/prettierCheck.js +16 -3
  15. package/dist/analyzers/prettierCheck.js.map +1 -1
  16. package/dist/analyzers/pythonDependencyRiskCheck.js +4 -17
  17. package/dist/analyzers/pythonDependencyRiskCheck.js.map +1 -1
  18. package/dist/analyzers/pythonLinterCheck.js +2 -12
  19. package/dist/analyzers/pythonLinterCheck.js.map +1 -1
  20. package/dist/analyzers/securityCheck.js +26 -9
  21. package/dist/analyzers/securityCheck.js.map +1 -1
  22. package/dist/analyzers/supplyChainCheck.js +6 -2
  23. package/dist/analyzers/supplyChainCheck.js.map +1 -1
  24. package/dist/analyzers/testCheck.js +10 -1
  25. package/dist/analyzers/testCheck.js.map +1 -1
  26. package/dist/analyzers/unusedDependencyCheck.js +8 -8
  27. package/dist/analyzers/unusedDependencyCheck.js.map +1 -1
  28. package/dist/cli/_shared.d.ts +2 -1
  29. package/dist/cli/_shared.js +14 -2
  30. package/dist/cli/_shared.js.map +1 -1
  31. package/dist/cli/commands/agentBrief.js +7 -1
  32. package/dist/cli/commands/agentBrief.js.map +1 -1
  33. package/dist/cli/commands/analyze.js.map +1 -1
  34. package/dist/cli/commands/applyFix.js +1 -1
  35. package/dist/cli/commands/applyFix.js.map +1 -1
  36. package/dist/cli/commands/audit.js +4 -2
  37. package/dist/cli/commands/audit.js.map +1 -1
  38. package/dist/cli/commands/badge.js.map +1 -1
  39. package/dist/cli/commands/bugHunt.js +2 -2
  40. package/dist/cli/commands/bugHunt.js.map +1 -1
  41. package/dist/cli/commands/ci.js.map +1 -1
  42. package/dist/cli/commands/claim.js +3 -3
  43. package/dist/cli/commands/claim.js.map +1 -1
  44. package/dist/cli/commands/collision.js +4 -2
  45. package/dist/cli/commands/collision.js.map +1 -1
  46. package/dist/cli/commands/coordinate.js +4 -2
  47. package/dist/cli/commands/coordinate.js.map +1 -1
  48. package/dist/cli/commands/coupling.js.map +1 -1
  49. package/dist/cli/commands/coverage.js.map +1 -1
  50. package/dist/cli/commands/dataflow.js.map +1 -1
  51. package/dist/cli/commands/dependencies.js +1 -1
  52. package/dist/cli/commands/dependencies.js.map +1 -1
  53. package/dist/cli/commands/diff.js.map +1 -1
  54. package/dist/cli/commands/doctor.js.map +1 -1
  55. package/dist/cli/commands/dogfood.js +30 -5
  56. package/dist/cli/commands/dogfood.js.map +1 -1
  57. package/dist/cli/commands/evidencePack.js.map +1 -1
  58. package/dist/cli/commands/explainIssue.js +1 -1
  59. package/dist/cli/commands/explainIssue.js.map +1 -1
  60. package/dist/cli/commands/feedback.js +19 -5
  61. package/dist/cli/commands/feedback.js.map +1 -1
  62. package/dist/cli/commands/file.js +1 -1
  63. package/dist/cli/commands/file.js.map +1 -1
  64. package/dist/cli/commands/fix.js.map +1 -1
  65. package/dist/cli/commands/fixSuggest.js +12 -4
  66. package/dist/cli/commands/fixSuggest.js.map +1 -1
  67. package/dist/cli/commands/hotspots.js.map +1 -1
  68. package/dist/cli/commands/impact.js +1 -1
  69. package/dist/cli/commands/impact.js.map +1 -1
  70. package/dist/cli/commands/init.js +13 -5
  71. package/dist/cli/commands/init.js.map +1 -1
  72. package/dist/cli/commands/installHook.js +2 -2
  73. package/dist/cli/commands/installHook.js.map +1 -1
  74. package/dist/cli/commands/mcp.js.map +1 -1
  75. package/dist/cli/commands/memory.js +5 -2
  76. package/dist/cli/commands/memory.js.map +1 -1
  77. package/dist/cli/commands/mergeRisk.js +1 -1
  78. package/dist/cli/commands/mergeRisk.js.map +1 -1
  79. package/dist/cli/commands/missionProof.js +13 -12
  80. package/dist/cli/commands/missionProof.js.map +1 -1
  81. package/dist/cli/commands/outdated.js +1 -1
  82. package/dist/cli/commands/outdated.js.map +1 -1
  83. package/dist/cli/commands/plugin.js +10 -6
  84. package/dist/cli/commands/plugin.js.map +1 -1
  85. package/dist/cli/commands/prDiff.js +1 -1
  86. package/dist/cli/commands/prDiff.js.map +1 -1
  87. package/dist/cli/commands/preflight.js +1 -5
  88. package/dist/cli/commands/preflight.js.map +1 -1
  89. package/dist/cli/commands/privacyCheck.js +3 -1
  90. package/dist/cli/commands/privacyCheck.js.map +1 -1
  91. package/dist/cli/commands/qualityScorecard.js.map +1 -1
  92. package/dist/cli/commands/recipes.js.map +1 -1
  93. package/dist/cli/commands/regressionPlan.js.map +1 -1
  94. package/dist/cli/commands/releaseTrain.js.map +1 -1
  95. package/dist/cli/commands/review.js +1 -1
  96. package/dist/cli/commands/review.js.map +1 -1
  97. package/dist/cli/commands/route.js.map +1 -1
  98. package/dist/cli/commands/search.js +5 -2
  99. package/dist/cli/commands/search.js.map +1 -1
  100. package/dist/cli/commands/semanticGraph.js.map +1 -1
  101. package/dist/cli/commands/session.js +2 -2
  102. package/dist/cli/commands/session.js.map +1 -1
  103. package/dist/cli/commands/start.js +3 -1177
  104. package/dist/cli/commands/start.js.map +1 -1
  105. package/dist/cli/commands/startAction.d.ts +36 -0
  106. package/dist/cli/commands/startAction.js +70 -0
  107. package/dist/cli/commands/startAction.js.map +1 -0
  108. package/dist/cli/commands/startConsole.d.ts +7 -0
  109. package/dist/cli/commands/startConsole.js +309 -0
  110. package/dist/cli/commands/startConsole.js.map +1 -0
  111. package/dist/cli/commands/startMissionBundle.d.ts +41 -0
  112. package/dist/cli/commands/startMissionBundle.js +645 -0
  113. package/dist/cli/commands/startMissionBundle.js.map +1 -0
  114. package/dist/cli/commands/startOutput.d.ts +31 -0
  115. package/dist/cli/commands/startOutput.js +232 -0
  116. package/dist/cli/commands/startOutput.js.map +1 -0
  117. package/dist/cli/commands/startShortcuts.d.ts +26 -0
  118. package/dist/cli/commands/startShortcuts.js +117 -0
  119. package/dist/cli/commands/startShortcuts.js.map +1 -0
  120. package/dist/cli/commands/telemetry.js +2 -1
  121. package/dist/cli/commands/telemetry.js.map +1 -1
  122. package/dist/cli/commands/trial.js +19 -4
  123. package/dist/cli/commands/trial.js.map +1 -1
  124. package/dist/cli/commands/understand.js +3 -1
  125. package/dist/cli/commands/understand.js.map +1 -1
  126. package/dist/cli/commands/upgrade.js.map +1 -1
  127. package/dist/cli/commands/watch.js +1 -1
  128. package/dist/cli/commands/watch.js.map +1 -1
  129. package/dist/cli/commands/workplan.js.map +1 -1
  130. package/dist/cli/commands/workspace.js +1 -1
  131. package/dist/cli/commands/workspace.js.map +1 -1
  132. package/dist/cli/commands/workspaces.js +1 -1
  133. package/dist/cli/commands/workspaces.js.map +1 -1
  134. package/dist/cli/index.js +2 -117
  135. package/dist/cli/index.js.map +1 -1
  136. package/dist/cli/registerCommands.d.ts +4 -0
  137. package/dist/cli/registerCommands.js +125 -0
  138. package/dist/cli/registerCommands.js.map +1 -0
  139. package/dist/core/adoption.d.ts +2 -1
  140. package/dist/core/adoption.js +40 -13
  141. package/dist/core/adoption.js.map +1 -1
  142. package/dist/core/agentBrief.js +19 -6
  143. package/dist/core/agentBrief.js.map +1 -1
  144. package/dist/core/applyFix.js.map +1 -1
  145. package/dist/core/ast.js +30 -19
  146. package/dist/core/ast.js.map +1 -1
  147. package/dist/core/auditRunner.js.map +1 -1
  148. package/dist/core/bugHunt.js +119 -17
  149. package/dist/core/bugHunt.js.map +1 -1
  150. package/dist/core/claims.js +5 -2
  151. package/dist/core/claims.js.map +1 -1
  152. package/dist/core/codeGraph.js +10 -0
  153. package/dist/core/codeGraph.js.map +1 -1
  154. package/dist/core/codeGraphReexports.d.ts +9 -0
  155. package/dist/core/codeGraphReexports.js +59 -0
  156. package/dist/core/codeGraphReexports.js.map +1 -0
  157. package/dist/core/collisionDetector.js +14 -4
  158. package/dist/core/collisionDetector.js.map +1 -1
  159. package/dist/core/coordination.js +4 -6
  160. package/dist/core/coordination.js.map +1 -1
  161. package/dist/core/couplingAnalyzer.d.ts +2 -1
  162. package/dist/core/couplingAnalyzer.js.map +1 -1
  163. package/dist/core/coverageParser.js.map +1 -1
  164. package/dist/core/dataflow.js +11 -2
  165. package/dist/core/dataflow.js.map +1 -1
  166. package/dist/core/dataflowFilters.js +8 -3
  167. package/dist/core/dataflowFilters.js.map +1 -1
  168. package/dist/core/dependencyAnalyzer.js +4 -1
  169. package/dist/core/dependencyAnalyzer.js.map +1 -1
  170. package/dist/core/dogfood.d.ts +1 -1
  171. package/dist/core/dogfood.js +39 -5
  172. package/dist/core/dogfood.js.map +1 -1
  173. package/dist/core/embeddings.js.map +1 -1
  174. package/dist/core/evidenceComment.js +34 -12
  175. package/dist/core/evidenceComment.js.map +1 -1
  176. package/dist/core/explainIssue.js +1 -2
  177. package/dist/core/explainIssue.js.map +1 -1
  178. package/dist/core/feedback.d.ts +1 -1
  179. package/dist/core/feedback.js +15 -4
  180. package/dist/core/feedback.js.map +1 -1
  181. package/dist/core/fileInspector.js +8 -2
  182. package/dist/core/fileInspector.js.map +1 -1
  183. package/dist/core/fixFirst.d.ts +3 -1
  184. package/dist/core/fixFirst.js +17 -4
  185. package/dist/core/fixFirst.js.map +1 -1
  186. package/dist/core/fixSuggest.js +20 -12
  187. package/dist/core/fixSuggest.js.map +1 -1
  188. package/dist/core/frameworkDetector.js +5 -3
  189. package/dist/core/frameworkDetector.js.map +1 -1
  190. package/dist/core/frameworkSources.js +22 -2
  191. package/dist/core/frameworkSources.js.map +1 -1
  192. package/dist/core/graphCorpus.d.ts +1 -1
  193. package/dist/core/graphCorpus.js +9 -1
  194. package/dist/core/graphCorpus.js.map +1 -1
  195. package/dist/core/graphQuery.js.map +1 -1
  196. package/dist/core/hotspotAnalyzer.js +26 -6
  197. package/dist/core/hotspotAnalyzer.js.map +1 -1
  198. package/dist/core/impact.d.ts +1 -1
  199. package/dist/core/impact.js.map +1 -1
  200. package/dist/core/importGraph.js.map +1 -1
  201. package/dist/core/indexCache.js.map +1 -1
  202. package/dist/core/intent.d.ts +1 -1
  203. package/dist/core/intent.js +143 -46
  204. package/dist/core/intent.js.map +1 -1
  205. package/dist/core/intentRouter.js +5467 -445
  206. package/dist/core/intentRouter.js.map +1 -1
  207. package/dist/core/issueEngine.js +1 -1
  208. package/dist/core/issueEngine.js.map +1 -1
  209. package/dist/core/languageDetector.js +1 -9
  210. package/dist/core/languageDetector.js.map +1 -1
  211. package/dist/core/languages/cppAdapter.js +3 -1
  212. package/dist/core/languages/cppAdapter.js.map +1 -1
  213. package/dist/core/languages/cppExports.js +6 -1
  214. package/dist/core/languages/cppExports.js.map +1 -1
  215. package/dist/core/languages/cppFunctions.js +3 -1
  216. package/dist/core/languages/cppFunctions.js.map +1 -1
  217. package/dist/core/languages/csharpAdapter.js.map +1 -1
  218. package/dist/core/languages/csharpFunctions.js +3 -1
  219. package/dist/core/languages/csharpFunctions.js.map +1 -1
  220. package/dist/core/languages/csharpImports.js +2 -1
  221. package/dist/core/languages/csharpImports.js.map +1 -1
  222. package/dist/core/languages/goAdapter.js.map +1 -1
  223. package/dist/core/languages/goExports.js.map +1 -1
  224. package/dist/core/languages/goFunctions.js +9 -3
  225. package/dist/core/languages/goFunctions.js.map +1 -1
  226. package/dist/core/languages/javaAdapter.js +1 -2
  227. package/dist/core/languages/javaAdapter.js.map +1 -1
  228. package/dist/core/languages/javaFunctions.js +6 -2
  229. package/dist/core/languages/javaFunctions.js.map +1 -1
  230. package/dist/core/languages/javascriptAdapter.js +43 -8
  231. package/dist/core/languages/javascriptAdapter.js.map +1 -1
  232. package/dist/core/languages/kotlinAdapter.js +5 -2
  233. package/dist/core/languages/kotlinAdapter.js.map +1 -1
  234. package/dist/core/languages/kotlinFunctions.js +5 -6
  235. package/dist/core/languages/kotlinFunctions.js.map +1 -1
  236. package/dist/core/languages/kotlinImports.js +3 -1
  237. package/dist/core/languages/kotlinImports.js.map +1 -1
  238. package/dist/core/languages/kotlinManifests.js +7 -1
  239. package/dist/core/languages/kotlinManifests.js.map +1 -1
  240. package/dist/core/languages/phpAdapter.js +4 -1
  241. package/dist/core/languages/phpAdapter.js.map +1 -1
  242. package/dist/core/languages/phpExports.js.map +1 -1
  243. package/dist/core/languages/phpFunctions.js +18 -6
  244. package/dist/core/languages/phpFunctions.js.map +1 -1
  245. package/dist/core/languages/phpManifests.js.map +1 -1
  246. package/dist/core/languages/pythonAdapter.js.map +1 -1
  247. package/dist/core/languages/pythonFunctions.js +9 -3
  248. package/dist/core/languages/pythonFunctions.js.map +1 -1
  249. package/dist/core/languages/pythonManifests.js.map +1 -1
  250. package/dist/core/languages/rubyAdapter.js.map +1 -1
  251. package/dist/core/languages/rubyFunctions.js +6 -2
  252. package/dist/core/languages/rubyFunctions.js.map +1 -1
  253. package/dist/core/languages/rustAdapter.js.map +1 -1
  254. package/dist/core/languages/rustFunctions.js +6 -2
  255. package/dist/core/languages/rustFunctions.js.map +1 -1
  256. package/dist/core/languages/swiftAdapter.js +3 -1
  257. package/dist/core/languages/swiftAdapter.js.map +1 -1
  258. package/dist/core/languages/swiftCyclomatic.js.map +1 -1
  259. package/dist/core/languages/swiftFunctions.js +3 -1
  260. package/dist/core/languages/swiftFunctions.js.map +1 -1
  261. package/dist/core/languages/swiftImports.js.map +1 -1
  262. package/dist/core/mergeRisk.js +5 -1
  263. package/dist/core/mergeRisk.js.map +1 -1
  264. package/dist/core/missionOutcome.d.ts +1 -1
  265. package/dist/core/missionOutcome.js +9 -4
  266. package/dist/core/missionOutcome.js.map +1 -1
  267. package/dist/core/missionProof.d.ts +1 -1
  268. package/dist/core/missionProof.js +8 -6
  269. package/dist/core/missionProof.js.map +1 -1
  270. package/dist/core/missionProofBaseline.d.ts +1 -1
  271. package/dist/core/missionProofBaseline.js +8 -2
  272. package/dist/core/missionProofBaseline.js.map +1 -1
  273. package/dist/core/missionProofMarkdown.d.ts +1 -1
  274. package/dist/core/missionProofMarkdown.js +4 -1
  275. package/dist/core/missionProofMarkdown.js.map +1 -1
  276. package/dist/core/missionProofSummary.d.ts +1 -1
  277. package/dist/core/monorepo.d.ts +1 -1
  278. package/dist/core/monorepo.js +4 -2
  279. package/dist/core/monorepo.js.map +1 -1
  280. package/dist/core/onboarding.d.ts +2 -1
  281. package/dist/core/onboarding.js.map +1 -1
  282. package/dist/core/outdatedDetector.js +5 -1
  283. package/dist/core/outdatedDetector.js.map +1 -1
  284. package/dist/core/ownership.js +3 -1
  285. package/dist/core/ownership.js.map +1 -1
  286. package/dist/core/pathClassifiers.js.map +1 -1
  287. package/dist/core/pluginDx.js +2 -1
  288. package/dist/core/pluginDx.js.map +1 -1
  289. package/dist/core/pluginTrust.js +1 -3
  290. package/dist/core/pluginTrust.js.map +1 -1
  291. package/dist/core/plugins.js +5 -5
  292. package/dist/core/plugins.js.map +1 -1
  293. package/dist/core/prDiff.d.ts +1 -2
  294. package/dist/core/prDiff.js +5 -1
  295. package/dist/core/prDiff.js.map +1 -1
  296. package/dist/core/preflight.js +15 -6
  297. package/dist/core/preflight.js.map +1 -1
  298. package/dist/core/privacy.js.map +1 -1
  299. package/dist/core/qualityScorecard.d.ts +1 -1
  300. package/dist/core/qualityScorecard.js +43 -11
  301. package/dist/core/qualityScorecard.js.map +1 -1
  302. package/dist/core/regressionPlan.js +25 -7
  303. package/dist/core/regressionPlan.js.map +1 -1
  304. package/dist/core/releaseEvidence.js +41 -17
  305. package/dist/core/releaseEvidence.js.map +1 -1
  306. package/dist/core/releaseTrain.js +66 -38
  307. package/dist/core/releaseTrain.js.map +1 -1
  308. package/dist/core/repositoryScanner.js +1 -3
  309. package/dist/core/repositoryScanner.js.map +1 -1
  310. package/dist/core/review.d.ts +1 -1
  311. package/dist/core/review.js +72 -10
  312. package/dist/core/review.js.map +1 -1
  313. package/dist/core/reviewDataflow.js +7 -1
  314. package/dist/core/reviewDataflow.js.map +1 -1
  315. package/dist/core/reviewPublicSurface.d.ts +13 -0
  316. package/dist/core/reviewPublicSurface.js +134 -0
  317. package/dist/core/reviewPublicSurface.js.map +1 -0
  318. package/dist/core/roadmapCatalog.js +122 -23
  319. package/dist/core/roadmapCatalog.js.map +1 -1
  320. package/dist/core/searchIndex.js +124 -17
  321. package/dist/core/searchIndex.js.map +1 -1
  322. package/dist/core/semanticGraph.js.map +1 -1
  323. package/dist/core/semanticSearch.js +20 -4
  324. package/dist/core/semanticSearch.js.map +1 -1
  325. package/dist/core/session.js +1 -2
  326. package/dist/core/session.js.map +1 -1
  327. package/dist/core/sessionResources.js +6 -2
  328. package/dist/core/sessionResources.js.map +1 -1
  329. package/dist/core/start.d.ts +3 -9
  330. package/dist/core/start.js +22 -3231
  331. package/dist/core/start.js.map +1 -1
  332. package/dist/core/startAdoptionLoop.d.ts +2 -0
  333. package/dist/core/startAdoptionLoop.js +41 -0
  334. package/dist/core/startAdoptionLoop.js.map +1 -0
  335. package/dist/core/startEvidence.d.ts +5 -0
  336. package/dist/core/startEvidence.js +62 -0
  337. package/dist/core/startEvidence.js.map +1 -0
  338. package/dist/core/startExecutionPlan.d.ts +16 -0
  339. package/dist/core/startExecutionPlan.js +185 -0
  340. package/dist/core/startExecutionPlan.js.map +1 -0
  341. package/dist/core/startHarness.d.ts +3 -0
  342. package/dist/core/startHarness.js +47 -0
  343. package/dist/core/startHarness.js.map +1 -0
  344. package/dist/core/startIntentTargets.d.ts +24 -0
  345. package/dist/core/startIntentTargets.js +1106 -0
  346. package/dist/core/startIntentTargets.js.map +1 -0
  347. package/dist/core/startMissionControl.d.ts +16 -0
  348. package/dist/core/startMissionControl.js +145 -0
  349. package/dist/core/startMissionControl.js.map +1 -0
  350. package/dist/core/startMissionPolicy.d.ts +19 -0
  351. package/dist/core/startMissionPolicy.js +246 -0
  352. package/dist/core/startMissionPolicy.js.map +1 -0
  353. package/dist/core/startMode.d.ts +11 -0
  354. package/dist/core/startMode.js +139 -0
  355. package/dist/core/startMode.js.map +1 -0
  356. package/dist/core/startOptions.d.ts +18 -0
  357. package/dist/core/startOptions.js +29 -0
  358. package/dist/core/startOptions.js.map +1 -0
  359. package/dist/core/startResume.d.ts +7 -0
  360. package/dist/core/startResume.js +468 -0
  361. package/dist/core/startResume.js.map +1 -0
  362. package/dist/core/startReviewGate.d.ts +11 -0
  363. package/dist/core/startReviewGate.js +200 -0
  364. package/dist/core/startReviewGate.js.map +1 -0
  365. package/dist/core/startRouteActions.d.ts +7 -0
  366. package/dist/core/startRouteActions.js +497 -0
  367. package/dist/core/startRouteActions.js.map +1 -0
  368. package/dist/core/startRunbook.d.ts +24 -0
  369. package/dist/core/startRunbook.js +271 -0
  370. package/dist/core/startRunbook.js.map +1 -0
  371. package/dist/core/startSuccessCriteria.d.ts +14 -0
  372. package/dist/core/startSuccessCriteria.js +497 -0
  373. package/dist/core/startSuccessCriteria.js.map +1 -0
  374. package/dist/core/taint.js +12 -3
  375. package/dist/core/taint.js.map +1 -1
  376. package/dist/core/telemetry.js +19 -5
  377. package/dist/core/telemetry.js.map +1 -1
  378. package/dist/core/trial.d.ts +1 -1
  379. package/dist/core/trial.js +15 -6
  380. package/dist/core/trial.js.map +1 -1
  381. package/dist/core/understand.d.ts +1 -1
  382. package/dist/core/understand.js +165 -51
  383. package/dist/core/understand.js.map +1 -1
  384. package/dist/core/upgradePreview.js +1 -1
  385. package/dist/core/upgradePreview.js.map +1 -1
  386. package/dist/core/watcher.js +18 -3
  387. package/dist/core/watcher.js.map +1 -1
  388. package/dist/core/workplan.js +87 -17
  389. package/dist/core/workplan.js.map +1 -1
  390. package/dist/core/workspace.js.map +1 -1
  391. package/dist/index.d.ts +9 -9
  392. package/dist/index.js +7 -7
  393. package/dist/index.js.map +1 -1
  394. package/dist/mcp/pagination.js.map +1 -1
  395. package/dist/mcp/prompts.js +28 -20
  396. package/dist/mcp/prompts.js.map +1 -1
  397. package/dist/mcp/server.js +6 -74
  398. package/dist/mcp/server.js.map +1 -1
  399. package/dist/mcp/serverPayload.d.ts +13 -0
  400. package/dist/mcp/serverPayload.js +61 -0
  401. package/dist/mcp/serverPayload.js.map +1 -0
  402. package/dist/mcp/tokenBudget.js.map +1 -1
  403. package/dist/mcp/tools/_shared.js.map +1 -1
  404. package/dist/mcp/tools/agentBrief.js +7 -1
  405. package/dist/mcp/tools/agentBrief.js.map +1 -1
  406. package/dist/mcp/tools/applyFix.js +1 -1
  407. package/dist/mcp/tools/applyFix.js.map +1 -1
  408. package/dist/mcp/tools/audit.js.map +1 -1
  409. package/dist/mcp/tools/bugHunt.js +2 -2
  410. package/dist/mcp/tools/bugHunt.js.map +1 -1
  411. package/dist/mcp/tools/claim.js +8 -3
  412. package/dist/mcp/tools/claim.js.map +1 -1
  413. package/dist/mcp/tools/collision.js +3 -1
  414. package/dist/mcp/tools/collision.js.map +1 -1
  415. package/dist/mcp/tools/coordinate.js.map +1 -1
  416. package/dist/mcp/tools/coordinateWatch.js +5 -2
  417. package/dist/mcp/tools/coordinateWatch.js.map +1 -1
  418. package/dist/mcp/tools/costSummary.js.map +1 -1
  419. package/dist/mcp/tools/coupling.js.map +1 -1
  420. package/dist/mcp/tools/coverage.js.map +1 -1
  421. package/dist/mcp/tools/dataflow.js.map +1 -1
  422. package/dist/mcp/tools/dependencies.js +4 -1
  423. package/dist/mcp/tools/dependencies.js.map +1 -1
  424. package/dist/mcp/tools/doctor.js.map +1 -1
  425. package/dist/mcp/tools/explainIssue.js +4 -1
  426. package/dist/mcp/tools/explainIssue.js.map +1 -1
  427. package/dist/mcp/tools/fixSuggest.js +5 -2
  428. package/dist/mcp/tools/fixSuggest.js.map +1 -1
  429. package/dist/mcp/tools/hotspots.js +4 -1
  430. package/dist/mcp/tools/hotspots.js.map +1 -1
  431. package/dist/mcp/tools/impact.js +10 -3
  432. package/dist/mcp/tools/impact.js.map +1 -1
  433. package/dist/mcp/tools/mergeRisk.js.map +1 -1
  434. package/dist/mcp/tools/plugin.js +6 -1
  435. package/dist/mcp/tools/plugin.js.map +1 -1
  436. package/dist/mcp/tools/prDiff.js.map +1 -1
  437. package/dist/mcp/tools/preflight.js +1 -5
  438. package/dist/mcp/tools/preflight.js.map +1 -1
  439. package/dist/mcp/tools/review.js.map +1 -1
  440. package/dist/mcp/tools/reviewWatch.d.ts +1 -1
  441. package/dist/mcp/tools/reviewWatch.js +9 -9
  442. package/dist/mcp/tools/reviewWatch.js.map +1 -1
  443. package/dist/mcp/tools/route.js +1 -1
  444. package/dist/mcp/tools/route.js.map +1 -1
  445. package/dist/mcp/tools/search.js.map +1 -1
  446. package/dist/mcp/tools/semanticGraph.js +8 -2
  447. package/dist/mcp/tools/semanticGraph.js.map +1 -1
  448. package/dist/mcp/tools/start.js.map +1 -1
  449. package/dist/mcp/tools/structure.js +7 -1
  450. package/dist/mcp/tools/structure.js.map +1 -1
  451. package/dist/mcp/tools/understand.js.map +1 -1
  452. package/dist/mcp/tools/workspaceGraph.js +10 -1
  453. package/dist/mcp/tools/workspaceGraph.js.map +1 -1
  454. package/dist/mcp/tools.js +3 -1
  455. package/dist/mcp/tools.js.map +1 -1
  456. package/dist/projscan-sbom.cdx.json +2136 -904
  457. package/dist/reporters/consoleAnalysisReporter.d.ts +2 -0
  458. package/dist/reporters/consoleAnalysisReporter.js +89 -0
  459. package/dist/reporters/consoleAnalysisReporter.js.map +1 -0
  460. package/dist/reporters/consoleArchitectureReporter.d.ts +3 -0
  461. package/dist/reporters/consoleArchitectureReporter.js +47 -0
  462. package/dist/reporters/consoleArchitectureReporter.js.map +1 -0
  463. package/dist/reporters/consoleAuditReporter.d.ts +2 -0
  464. package/dist/reporters/consoleAuditReporter.js +46 -0
  465. package/dist/reporters/consoleAuditReporter.js.map +1 -0
  466. package/dist/reporters/consoleCiReporter.d.ts +2 -0
  467. package/dist/reporters/consoleCiReporter.js +27 -0
  468. package/dist/reporters/consoleCiReporter.js.map +1 -0
  469. package/dist/reporters/consoleCouplingReporter.d.ts +2 -0
  470. package/dist/reporters/consoleCouplingReporter.js +53 -0
  471. package/dist/reporters/consoleCouplingReporter.js.map +1 -0
  472. package/dist/reporters/consoleCoverageReporter.d.ts +2 -0
  473. package/dist/reporters/consoleCoverageReporter.js +62 -0
  474. package/dist/reporters/consoleCoverageReporter.js.map +1 -0
  475. package/dist/reporters/consoleDependencyReporter.d.ts +2 -0
  476. package/dist/reporters/consoleDependencyReporter.js +64 -0
  477. package/dist/reporters/consoleDependencyReporter.js.map +1 -0
  478. package/dist/reporters/consoleDiffReporter.d.ts +2 -0
  479. package/dist/reporters/consoleDiffReporter.js +80 -0
  480. package/dist/reporters/consoleDiffReporter.js.map +1 -0
  481. package/dist/reporters/consoleExplanationReporter.d.ts +2 -0
  482. package/dist/reporters/consoleExplanationReporter.js +33 -0
  483. package/dist/reporters/consoleExplanationReporter.js.map +1 -0
  484. package/dist/reporters/consoleFileReporter.d.ts +2 -0
  485. package/dist/reporters/consoleFileReporter.js +133 -0
  486. package/dist/reporters/consoleFileReporter.js.map +1 -0
  487. package/dist/reporters/consoleFixGuidanceReporter.d.ts +8 -0
  488. package/dist/reporters/consoleFixGuidanceReporter.js +135 -0
  489. package/dist/reporters/consoleFixGuidanceReporter.js.map +1 -0
  490. package/dist/reporters/consoleHealthReporter.d.ts +13 -0
  491. package/dist/reporters/consoleHealthReporter.js +111 -0
  492. package/dist/reporters/consoleHealthReporter.js.map +1 -0
  493. package/dist/reporters/consoleHotspotReporter.d.ts +2 -0
  494. package/dist/reporters/consoleHotspotReporter.js +68 -0
  495. package/dist/reporters/consoleHotspotReporter.js.map +1 -0
  496. package/dist/reporters/consoleImpactReporter.d.ts +2 -0
  497. package/dist/reporters/consoleImpactReporter.js +65 -0
  498. package/dist/reporters/consoleImpactReporter.js.map +1 -0
  499. package/dist/reporters/consoleOutdatedReporter.d.ts +2 -0
  500. package/dist/reporters/consoleOutdatedReporter.js +54 -0
  501. package/dist/reporters/consoleOutdatedReporter.js.map +1 -0
  502. package/dist/reporters/consolePrDiffReporter.d.ts +2 -0
  503. package/dist/reporters/consolePrDiffReporter.js +75 -0
  504. package/dist/reporters/consolePrDiffReporter.js.map +1 -0
  505. package/dist/reporters/consoleReporter.d.ts +21 -38
  506. package/dist/reporters/consoleReporter.js +19 -1000
  507. package/dist/reporters/consoleReporter.js.map +1 -1
  508. package/dist/reporters/consoleReviewReporter.d.ts +2 -0
  509. package/dist/reporters/consoleReviewReporter.js +101 -0
  510. package/dist/reporters/consoleReviewReporter.js.map +1 -0
  511. package/dist/reporters/consoleUpgradeReporter.d.ts +2 -0
  512. package/dist/reporters/consoleUpgradeReporter.js +67 -0
  513. package/dist/reporters/consoleUpgradeReporter.js.map +1 -0
  514. package/dist/reporters/consoleWorkspaceReporter.d.ts +2 -0
  515. package/dist/reporters/consoleWorkspaceReporter.js +24 -0
  516. package/dist/reporters/consoleWorkspaceReporter.js.map +1 -0
  517. package/dist/reporters/htmlReporter.d.ts +2 -1
  518. package/dist/reporters/htmlReporter.js +9 -3
  519. package/dist/reporters/htmlReporter.js.map +1 -1
  520. package/dist/reporters/jsonReporter.d.ts +2 -1
  521. package/dist/reporters/jsonReporter.js.map +1 -1
  522. package/dist/reporters/markdownAnalysisReporter.d.ts +2 -0
  523. package/dist/reporters/markdownAnalysisReporter.js +40 -0
  524. package/dist/reporters/markdownAnalysisReporter.js.map +1 -0
  525. package/dist/reporters/markdownAuditReporter.d.ts +2 -0
  526. package/dist/reporters/markdownAuditReporter.js +27 -0
  527. package/dist/reporters/markdownAuditReporter.js.map +1 -0
  528. package/dist/reporters/markdownDependencyReporter.d.ts +2 -0
  529. package/dist/reporters/markdownDependencyReporter.js +33 -0
  530. package/dist/reporters/markdownDependencyReporter.js.map +1 -0
  531. package/dist/reporters/markdownDiffReporter.d.ts +2 -0
  532. package/dist/reporters/markdownDiffReporter.js +65 -0
  533. package/dist/reporters/markdownDiffReporter.js.map +1 -0
  534. package/dist/reporters/markdownFileReporter.d.ts +2 -0
  535. package/dist/reporters/markdownFileReporter.js +92 -0
  536. package/dist/reporters/markdownFileReporter.js.map +1 -0
  537. package/dist/reporters/markdownFixGuidanceReporter.d.ts +8 -0
  538. package/dist/reporters/markdownFixGuidanceReporter.js +95 -0
  539. package/dist/reporters/markdownFixGuidanceReporter.js.map +1 -0
  540. package/dist/reporters/markdownImpactReporter.d.ts +2 -0
  541. package/dist/reporters/markdownImpactReporter.js +52 -0
  542. package/dist/reporters/markdownImpactReporter.js.map +1 -0
  543. package/dist/reporters/markdownReporter.d.ts +10 -16
  544. package/dist/reporters/markdownReporter.js +9 -452
  545. package/dist/reporters/markdownReporter.js.map +1 -1
  546. package/dist/reporters/markdownReviewReporter.d.ts +2 -0
  547. package/dist/reporters/markdownReviewReporter.js +84 -0
  548. package/dist/reporters/markdownReviewReporter.js.map +1 -0
  549. package/dist/reporters/markdownUpgradeReporter.d.ts +2 -0
  550. package/dist/reporters/markdownUpgradeReporter.js +47 -0
  551. package/dist/reporters/markdownUpgradeReporter.js.map +1 -0
  552. package/dist/reporters/sarifReporter.js.map +1 -1
  553. package/dist/tool-manifest.json +4 -4
  554. package/dist/types/agentBrief.d.ts +48 -0
  555. package/dist/types/agentBrief.js +2 -0
  556. package/dist/types/agentBrief.js.map +1 -0
  557. package/dist/types/analysis.d.ts +32 -0
  558. package/dist/types/analysis.js +2 -0
  559. package/dist/types/analysis.js.map +1 -0
  560. package/dist/types/baseline.d.ts +59 -0
  561. package/dist/types/baseline.js +2 -0
  562. package/dist/types/baseline.js.map +1 -0
  563. package/dist/types/bugHunt.d.ts +41 -0
  564. package/dist/types/bugHunt.js +2 -0
  565. package/dist/types/bugHunt.js.map +1 -0
  566. package/dist/types/common.d.ts +34 -0
  567. package/dist/types/common.js +2 -0
  568. package/dist/types/common.js.map +1 -0
  569. package/dist/types/config.d.ts +56 -0
  570. package/dist/types/config.js +2 -0
  571. package/dist/types/config.js.map +1 -0
  572. package/dist/types/coupling.d.ts +40 -0
  573. package/dist/types/coupling.js +2 -0
  574. package/dist/types/coupling.js.map +1 -0
  575. package/dist/types/coverage.d.ts +32 -0
  576. package/dist/types/coverage.js +2 -0
  577. package/dist/types/coverage.js.map +1 -0
  578. package/dist/types/dependencyHealth.d.ts +61 -0
  579. package/dist/types/dependencyHealth.js +2 -0
  580. package/dist/types/dependencyHealth.js.map +1 -0
  581. package/dist/types/dogfood.d.ts +185 -0
  582. package/dist/types/dogfood.js +2 -0
  583. package/dist/types/dogfood.js.map +1 -0
  584. package/dist/types/evidencePack.d.ts +76 -0
  585. package/dist/types/evidencePack.js +2 -0
  586. package/dist/types/evidencePack.js.map +1 -0
  587. package/dist/types/fixes.d.ts +77 -0
  588. package/dist/types/fixes.js +2 -0
  589. package/dist/types/fixes.js.map +1 -0
  590. package/dist/types/graph.d.ts +80 -0
  591. package/dist/types/graph.js +2 -0
  592. package/dist/types/graph.js.map +1 -0
  593. package/dist/types/graphCorpus.d.ts +16 -0
  594. package/dist/types/graphCorpus.js +2 -0
  595. package/dist/types/graphCorpus.js.map +1 -0
  596. package/dist/types/hotspots.d.ts +42 -0
  597. package/dist/types/hotspots.js +2 -0
  598. package/dist/types/hotspots.js.map +1 -0
  599. package/dist/types/impact.d.ts +62 -0
  600. package/dist/types/impact.js +2 -0
  601. package/dist/types/impact.js.map +1 -0
  602. package/dist/types/inspection.d.ts +47 -0
  603. package/dist/types/inspection.js +2 -0
  604. package/dist/types/inspection.js.map +1 -0
  605. package/dist/types/mcp.d.ts +39 -0
  606. package/dist/types/mcp.js +2 -0
  607. package/dist/types/mcp.js.map +1 -0
  608. package/dist/types/pluginDx.d.ts +42 -0
  609. package/dist/types/pluginDx.js +2 -0
  610. package/dist/types/pluginDx.js.map +1 -0
  611. package/dist/types/prDiff.d.ts +41 -0
  612. package/dist/types/prDiff.js +2 -0
  613. package/dist/types/prDiff.js.map +1 -0
  614. package/dist/types/preflight.d.ts +122 -0
  615. package/dist/types/preflight.js +2 -0
  616. package/dist/types/preflight.js.map +1 -0
  617. package/dist/types/qualityScorecard.d.ts +34 -0
  618. package/dist/types/qualityScorecard.js +2 -0
  619. package/dist/types/qualityScorecard.js.map +1 -0
  620. package/dist/types/regressionPlan.d.ts +32 -0
  621. package/dist/types/regressionPlan.js +2 -0
  622. package/dist/types/regressionPlan.js.map +1 -0
  623. package/dist/types/releaseTrain.d.ts +37 -0
  624. package/dist/types/releaseTrain.js +2 -0
  625. package/dist/types/releaseTrain.js.map +1 -0
  626. package/dist/types/review.d.ts +203 -0
  627. package/dist/types/review.js +2 -0
  628. package/dist/types/review.js.map +1 -0
  629. package/dist/types/reviewContract.d.ts +9 -0
  630. package/dist/types/reviewContract.js +2 -0
  631. package/dist/types/reviewContract.js.map +1 -0
  632. package/dist/types/scanning.d.ts +111 -0
  633. package/dist/types/scanning.js +2 -0
  634. package/dist/types/scanning.js.map +1 -0
  635. package/dist/types/session.d.ts +42 -0
  636. package/dist/types/session.js +2 -0
  637. package/dist/types/session.js.map +1 -0
  638. package/dist/types/start.d.ts +437 -0
  639. package/dist/types/start.js +2 -0
  640. package/dist/types/start.js.map +1 -0
  641. package/dist/types/trial.d.ts +27 -0
  642. package/dist/types/trial.js +2 -0
  643. package/dist/types/trial.js.map +1 -0
  644. package/dist/types/understand.d.ts +153 -0
  645. package/dist/types/understand.js +2 -0
  646. package/dist/types/understand.js.map +1 -0
  647. package/dist/types/workplan.d.ts +67 -0
  648. package/dist/types/workplan.js +2 -0
  649. package/dist/types/workplan.js.map +1 -0
  650. package/dist/types/workplanHandoff.d.ts +11 -0
  651. package/dist/types/workplanHandoff.js +2 -0
  652. package/dist/types/workplanHandoff.js.map +1 -0
  653. package/dist/types/workspace.d.ts +18 -0
  654. package/dist/types/workspace.js +2 -0
  655. package/dist/types/workspace.js.map +1 -0
  656. package/dist/types.d.ts +34 -2348
  657. package/dist/types.js +0 -1
  658. package/dist/types.js.map +1 -1
  659. package/dist/utils/banner.js +15 -6
  660. package/dist/utils/banner.js.map +1 -1
  661. package/dist/utils/baseline.js +11 -9
  662. package/dist/utils/baseline.js.map +1 -1
  663. package/dist/utils/changedFiles.js +1 -1
  664. package/dist/utils/changedFiles.js.map +1 -1
  665. package/dist/utils/config.d.ts +2 -1
  666. package/dist/utils/config.js.map +1 -1
  667. package/dist/utils/formatSupport.d.ts +1 -1
  668. package/dist/utils/formatSupport.js +7 -1
  669. package/dist/utils/formatSupport.js.map +1 -1
  670. package/dist/utils/packageJsonLocator.js.map +1 -1
  671. package/docs/GUIDE.md +186 -146
  672. package/docs/PLUGIN-GALLERY.md +9 -1
  673. package/docs/ROADMAP.md +69 -68
  674. package/docs/demos/projscan-4-1-demo.html +46 -79
  675. package/docs/examples/plugins/graph-context.mjs +1 -2
  676. package/docs/examples/plugins/security-sensitive-files.mjs +2 -1
  677. package/package.json +10 -5
package/docs/GUIDE.md CHANGED
@@ -112,7 +112,7 @@ projscan is structured around the four questions an AI coding agent (or a carefu
112
112
 
113
113
  ### 1. Diagnose — "what's wrong here?"
114
114
 
115
- When the agent first opens a repo, or before starting a refactor, the question is: *is anything obviously broken or risky?*
115
+ When the agent first opens a repo, or before starting a refactor, the question is: _is anything obviously broken or risky?_
116
116
 
117
117
  - **`projscan privacy-check`** — trust boundary report. Shows telemetry/offline status, scan root, Git ignore handling, `.env` content handling, plugin execution status, local write surfaces, report-export sensitivity, and network-capable endpoints.
118
118
  - **`projscan_start` / `projscan start`** — first-60-seconds workflow orientation. Composes setup diagnostics, Mission Control, the recommended workflow recipe, `firstTenMinutes`, workplan, quality scorecard, top risks, adoption gaps, repeat-use metrics, next commands, optional handoff payload, and a split between current Git/worktree evidence and remembered session context. Pass `intent` / `--intent "<goal>"` when the developer or agent wants one routed action plan with route confidence, immediately callable `readyActions`, and proof commands, such as `projscan start --intent "what breaks if I rename this API?"`. For fuzzy impact targets, Mission Control searches first, then gives symbol and file impact follow-ups for the search result. For exact symbols or paths, such as `projscan start --intent "what breaks if I change src/core/start.ts?"`, `projscan start --intent "where is runAudit used?"`, `projscan start --intent "what depends on src/core/start.ts?"`, or `projscan start --intent "can I delete src/core/start.ts?"`, it runs impact directly. For repo-orientation questions, such as `projscan start --intent "summarize this repo"`, `projscan start --intent "what files should I read first?"`, `projscan start --intent "where do I start in this codebase?"`, `projscan start --intent "give me a tour of the repo"`, or `projscan start --intent "explain the architecture"`, it routes to `projscan_understand --view map` so the developer gets cited read-first files, entrypoints, boundaries, risks, and unknowns. For public surface questions, such as `projscan start --intent "what are the public contracts?"` or `projscan start --intent "how do I safely deprecate this API?"`, it routes to `projscan_understand --view contracts` so public exports, config contracts, and likely breaking-change risks are reviewed before touching API surfaces. For API breakage questions, such as `projscan start --intent "what will this API change break?"`, it searches for the exact public symbol or file before continuing to impact analysis. For broad quality/risk questions, such as `projscan start --intent "what is risky in this repo?"`, it routes to `projscan_quality_scorecard` so health, security, tests, maintainability, coordination, and top risks are reviewed before choosing work. For file-orientation questions, such as `projscan start --intent "what should I read before changing src/core/start.ts?"`, `projscan start --intent "explain src/core/start.ts"`, `projscan start --intent "who owns src/core/start.ts?"`, `projscan start --intent "who should review src/core/start.ts?"`, or `projscan start --intent "who last touched src/core/start.ts?"`, it routes to `projscan_file` so the developer sees purpose, imports, exports, ownership, history, reviewer context, and risk before editing. For targeted graph questions, such as `projscan start --intent "who imports src/core/start.ts?"`, it routes to `projscan_semantic_graph` query mode instead of dumping the full graph. For security source-to-sink questions, such as `projscan start --intent "is user input reaching SQL sinks?"`, it routes to `projscan_dataflow` and infers the `hardening` workflow. For coverage-gap questions, such as `projscan start --intent "what are the scariest untested files?"`, it routes to `projscan_coverage` so the next test target is chosen by risk. For dependency inventory questions, such as `projscan start --intent "what dependencies does this repo use?"`, it routes to `projscan_dependencies` instead of an upgrade preview. For dependency vulnerability questions, such as `projscan start --intent "does lodash have a CVE?"`, `projscan start --intent "what CVEs affect this repo?"`, or `projscan start --intent "find vulnerable packages"`, it routes to `projscan_audit`, scoped with `--package` when the package can be inferred. For package-bump or package-update questions, such as `projscan start --intent "what breaks if I bump chalk to 6?"` or `projscan start --intent "what breaks if I update react?"`, it routes to `projscan_upgrade`; if no package is named, Mission Control runs `projscan outdated --format json` first and marks the package name as `Needs Input`. For "what changed in this PR?", it routes to `projscan_pr_diff` before full review. For "what should I fix first?" or "what is the fastest safe fix?", it routes to `projscan_bug_hunt` instead of issue-specific fix-suggest or generic preflight. For open-ended next-step questions, such as `projscan start --intent "what should I do next?"`, it routes to `projscan_workplan --mode before_edit` so the developer gets an ordered plan with verification before editing. For "give the next agent a handoff", it routes to `projscan_agent_brief` with `intent: "next_agent"`. For issue context, such as `projscan start --intent "explain issue missing-test-framework"`, it routes to `projscan_explain_issue`; if no issue id is named, Mission Control runs `projscan doctor --format json` first and marks the issue id as `Needs Input`. For direct issue repair, such as `projscan start --intent "fix issue missing-test-framework"`, it routes to `projscan_fix_suggest`; if no issue id is named, Mission Control runs `projscan doctor --format json` first and marks the fix-suggest issue id as `Needs Input`. For failing CI or tests, such as `projscan start --intent "CI is failing after this PR"`, it routes to `projscan_regression_plan` with a focused verification plan. For right-sized verification questions, such as `projscan start --intent "what smoke checks should I run before commit?"` or `projscan start --intent "what full regression should I run before merge?"`, Mission Control preserves the requested `smoke` or `full` regression depth.
@@ -180,7 +180,9 @@ When the agent first opens a repo, or before starting a refactor, the question i
180
180
  For short proof-command phrasing, such as `projscan start --intent "give me proof commands"`, it also routes to `projscan_regression_plan --level focused`; reviewer-proof wording with PR comments still routes to `projscan_evidence_pack`.
181
181
  For pre-push command questions, such as `projscan start --intent "what commands should I run before pushing?"`, it routes to `projscan_regression_plan --level focused` so the branch has a small verification loop before it leaves the workstation.
182
182
  For release-readiness wording, such as `projscan start --intent "what should I check before release?"`, `projscan start --intent "can I deploy this?"`, `projscan start --intent "prepare this branch for deployment"`, `projscan start --intent "what changed since last release?"`, `projscan start --intent "write a release note for this change"`, or `projscan start --intent "draft changelog entry"`, it routes to `projscan_release_train` so changelog, package, SBOM, provenance, and blockers are reviewed before deploying or publishing.
183
- For quick-win and low-risk improvement wording, such as `projscan start --intent "find a quick win"`, `projscan start --intent "what is a low risk improvement?"`, or `projscan start --intent "pick a small safe task"`, it routes to `projscan_bug_hunt` so a ranked, verifiable fix queue is selected instead of a generic quality readout.
183
+ For product-planning questions, such as `projscan start --intent "what should we build next?"` or `projscan start --intent "plan the product roadmap"`, it routes to `projscan_workplan --mode bug_hunt` so broad product direction becomes an ordered, verifiable product-planning workplan with explicit accept, defer, or split criteria instead of a generic before-edit orientation.
184
+ For broad improvement-planning questions, such as `projscan start --intent "what should we improve next?"`, it routes to `projscan_bug_hunt` so the agent gets an actionable ranked queue; technical variants such as tests, performance, release, dependencies, or safety keep their specialized routes.
185
+ For quick-win and low-risk improvement wording, such as `projscan start --intent "find a quick win"`, `projscan start --intent "what is a low risk improvement?"`, or `projscan start --intent "pick a small safe task"`, it routes to `projscan_bug_hunt` so a ranked, verifiable action queue is selected instead of a generic quality readout.
184
186
  For tiny-task and beginner-safe wording, such as `projscan start --intent "what can I do in five minutes?"`, `projscan start --intent "pick an easy task for me"`, or `projscan start --intent "what should an intern work on?"`, it also routes to `projscan_bug_hunt`.
185
187
  For branch-diff, PR-size, and commit-message questions, such as `projscan start --intent "what did I change since main?"`, `projscan start --intent "is this PR too large?"`, `projscan start --intent "how big is this change?"`, `projscan start --intent "write a commit message for these changes"`, or `projscan start --intent "summarize my changes for a commit"`, it routes to `projscan_pr_diff` so changed exports, imports, call sites, complexity, and fan-in are reviewed before full review.
186
188
  For branch freshness and comparison questions, such as `projscan start --intent "is my branch stale?"` or `projscan start --intent "compare my branch with main"`, it also routes to `projscan_pr_diff` so the developer checks the structural diff before rebasing or asking for review. For rebase and merge-conflict recovery, such as `projscan start --intent "rebase went wrong"` or `projscan start --intent "resolve merge conflicts"`, it routes to `projscan_preflight --mode before_merge`; post-conflict test-plan wording such as `projscan start --intent "what should I test after resolving conflicts?"` stays on `projscan_regression_plan`.
@@ -190,7 +192,7 @@ When the agent first opens a repo, or before starting a refactor, the question i
190
192
  For file-claim requests, such as `projscan start --intent "claim src/core/start.ts for me"`, it routes to `projscan_claim`, lists active claims first, then adds the requested target only after a real agent name replaces `Needs Input`.
191
193
  For architecture-coupling questions, such as `projscan start --intent "show circular dependencies"` or `projscan start --intent "find dependency cycles"`, it routes to `projscan_coupling` with `direction: "cycles_only"` / `projscan coupling --cycles-only --format json`; broader wording such as `projscan start --intent "what modules are tightly coupled"` routes to the full fan-in, fan-out, instability, cross-package-edge, and cycle report.
192
194
  - **`projscan_workplan` / `projscan workplan`** — agent mission control. Composes preflight, review, session, hotspot, plugin-policy, and supply-chain evidence into prioritized tasks with suggested tools, exact verification commands, and short handoff text. Modes: `before_edit`, `before_commit`, `before_merge`, `refactor`, `release`, `bug_hunt`, and `hardening`.
193
- - **`projscan_bug_hunt` / `projscan bug-hunt`** — bug-hunt fix queue. Combines doctor issues, preflight, hotspots, and session coordination into ranked fix targets with verification commands; pure hotspot churn stays as watchlist/top-suspect evidence when health and gates are clean.
195
+ - **`projscan_bug_hunt` / `projscan bug-hunt`** — bug-hunt action queue. Combines doctor issues, preflight, hotspots, and session coordination into ranked actions with verification commands; release-scale findings can be manual sign-off actions, while pure hotspot churn stays as watchlist/top-suspect evidence when health and gates are clean.
194
196
  - **`projscan_agent_brief` / `projscan agent-brief`** — compact next-agent context packet with focus items, repo context, coordination hints, guardrails, and suggested next actions.
195
197
  - **`projscan_quality_scorecard` / `projscan quality-scorecard`** — dimensioned quality view across health, security, tests, maintainability, coordination, top risks, and verification commands.
196
198
  - **`projscan_understand` / `projscan understand`** — cited repo-comprehension surface. Returns repo maps, runtime flow maps, contract maps, change-readiness guidance, verification tiers, unknowns, read-first files, and exact next commands.
@@ -206,7 +208,7 @@ When the agent first opens a repo, or before starting a refactor, the question i
206
208
  - **`projscan_coupling` / `projscan coupling`** — per-file fan-in / fan-out / instability plus circular-import cycles (Tarjan SCC). Use `direction: cycles_only` or `projscan coupling --cycles-only` to surface architectural debt directly.
207
209
  - **`projscan_analyze` / `projscan analyze`** — the everything report; useful at session start but verbose.
208
210
 
209
- **Typical agent flow:** start with `projscan privacy-check`, then `projscan_start` with an optional plain-language intent. If no explicit mode is supplied, start infers the workflow mode from the intent, such as `before_commit` for commit-safety checks; read `modeSource` and `modeReason` to see whether the mode was explicit, inferred, or defaulted. `modeReason` distinguishes workflow-mode defaulting from action routing, so an impact intent can still route through Mission Control while the workflow stays `before_edit`. The `firstTenMinutes` path and current-worktree coordination hint follow that resolved mode, so a commit-safety start does not send the developer back through a before-edit gate. Follow `missionControl.actionPlan`, call `missionControl.readyActions` immediately, use `missionControl.executionPlan.currentPhase` as the cursor-aligned phase pointer, and use `missionControl.executionPlan.cursor.tool` / `args` when the cursor is directly MCP-callable. Use routed-intent weighted `confidence`, `score`, and `matchedKeywords` to judge weak or ambiguous matches, and read the same confidence line in console output when working manually. Fill any `missionControl.unresolvedInputs` before running placeholder follow-ups, inspect `missionControl.alternatives` when the intent mixes goals, stop only when `missionControl.successCriteria` is satisfied, and hand off with `missionControl.handoff`, `missionControl.runbook`, or the concise `missionControl.handoffPrompt`. Use `missionControl.reviewGate` as the autonomous-work stop boundary: finish the current checklist and proof, capture `git status --short` and `git diff --stat`, then wait for approval before another slice, release, publish, or deploy. Read `missionControl.reviewGate.worktree` for current worktree availability, changed-file count, base ref, and visible changed files. Use `missionControl.reviewGate.proof` when the reviewer needs the remaining proof queue without reading the full resume object. Read `missionControl.reviewGate.doneWhen` for the success criteria the reviewer must confirm before approving more work. Read `missionControl.reviewGate.policy` before continuing from a review handoff; it lists the actions blocked until explicit reviewer approval: another slice, release, publish, deploy, push, merge, and version bump. Use `projscan start --review-gate-json --intent "<goal>"` or saved `review-gate.json` when a script needs proof, worktree evidence, done criteria, decisions, and policy in one review object. Use `projscan start --review-policy --intent "<goal>"` or saved `review-policy.json` when a script only needs that approval boundary. Use `missionControl.reviewGate.decisions` as the approval menu in review gates, task cards, and runbooks; each decision includes copyable reviewer reply text so agents do not infer permission to continue, release, or publish. The default console review gate, saved mission bundle README, concise handoff prompt, `--review-replies`, and saved `review-replies.txt` show those replies for first-open review. `missionControl.handoff.reviewGate`, `--handoff-json`, and saved `handoff.json` carry that same gate for transfer-only flows. The handoff prompt starts with `missionControl.resume.prompt`, so it carries the current cursor, runnable command or blocked input instruction, labeled unlocks or blockers, done criteria, ready proof, review stop condition, and reviewer replies in one copyable sentence; the normal console prints that same value as `Handoff Prompt` without requiring JSON or `--include-handoff`, `projscan start --handoff-prompt --intent "<goal>"` prints only that prompt for piping or copy/paste, and the Markdown runbook renders it as `## Handoff Prompt` so copied runbooks carry the same next-agent prompt. When a human just needs the runnable shell step, `projscan start --next-command --intent "<goal>"` prints only the current cursor command; when an MCP agent needs the callable equivalent, `projscan start --next-tool-call --intent "<goal>"` prints the current cursor tool call as compact JSON. Cite `missionControl.proofSummary` plus the runnable-only `missionControl.proofCommands` in broad handoff notes, and use `missionControl.handoff.readyProof.items` when resuming because it is the complete ordered remaining-proof queue; each item carries its CLI command and an optional MCP `toolCall`. `missionControl.handoff.readyProof.commands` and `toolCalls` remain convenient command-only and MCP-callable views. MCP agents should use `missionControl.resume.toolCall` when present, use `missionControl.resume.inputBindings` to map unlocked placeholders to input steps, then call `missionControl.resume.followUps` as the next template calls; when they need one ordered sequence, follow `missionControl.resume.checklist`, whose `run_proof` rows include `tool` and `args` for MCP-callable proof steps. The normal console `Resume Checklist` and Markdown runbook checklist print callable rows inline as `(MCP: ...)` and mark unmapped proof rows as `(CLI only)`, so a copied runbook or default terminal run remains self-contained even outside the JSON payload. After the current action, prefer `missionControl.resume.remainingProofItems` for complete proof, using `remainingProofToolCalls` for the callable MCP subset without rerunning the current command. Humans can run the matching `command`; the normal console `Ready Proof` command list, normal console `Proof Queue`, and runbook `Proof queue` all use remaining proof so the current cursor command is not repeated, and each queued item shows either its MCP call or `CLI only`. Use `projscan_understand` and `projscan_preflight` when you need broader context or a safety gate. Use `projscan_workplan` when you need an ordered execution plan, `projscan_agent_brief` for a compact handoff, and `projscan_evidence_pack --pr-comment` when you need reviewer-facing proof. Deeper tools such as `doctor`, `hotspots`, `dataflow`, `review`, `bug-hunt`, `quality-scorecard`, `dogfood`, and `trial` are follow-up tools.
211
+ **Typical agent flow:** start with `projscan privacy-check`, then `projscan_start` with an optional plain-language intent. If no explicit mode is supplied, start infers the workflow mode from the intent, such as `before_commit` for commit-safety checks; read `modeSource` and `modeReason` to see whether the mode was explicit, inferred, or defaulted. `modeReason` distinguishes workflow-mode defaulting from action routing, so an impact intent can still route through Mission Control while the workflow stays `before_edit`. The `firstTenMinutes` path and current-worktree coordination hint follow that resolved mode, so a commit-safety start does not send the developer back through a before-edit gate. Follow `missionControl.actionPlan`, call `missionControl.readyActions` immediately, use `missionControl.executionPlan.currentPhase` as the cursor-aligned phase pointer, and use `missionControl.executionPlan.cursor.tool` / `args` when the cursor is directly MCP-callable. Use routed-intent weighted `confidence`, `score`, and `matchedKeywords` to judge weak or ambiguous matches, and read the same confidence line in console output when working manually. Fill any `missionControl.unresolvedInputs` before running placeholder follow-ups, inspect `missionControl.alternatives` when the intent mixes goals, stop only when `missionControl.successCriteria` is satisfied, and hand off with `missionControl.handoff`, `missionControl.runbook`, or the concise `missionControl.handoffPrompt`. Use `missionControl.reviewGate` as the autonomous-work stop boundary: finish the current checklist and proof, capture `git status --short` and `git diff --stat`, then wait for approval before another slice, release, publish, or deploy. Read `missionControl.reviewGate.worktree` for current worktree availability, changed-file count, base ref, and visible changed files. Use `missionControl.reviewGate.proof` when the reviewer needs the remaining proof queue without reading the full resume object. Read `missionControl.reviewGate.doneWhen` for the success criteria the reviewer must confirm before approving more work. Read `missionControl.reviewGate.policy` before continuing from a review handoff; it lists the actions blocked until explicit reviewer approval: another slice, release, publish, deploy, push, merge, and version bump. Use `projscan start --review-gate-json --intent "<goal>"` or saved `review-gate.json` when a script needs proof, worktree evidence, done criteria, decisions, and policy in one review object. Use `projscan start --review-policy --intent "<goal>"` or saved `review-policy.json` when a script only needs that approval boundary. Use `missionControl.reviewGate.decisions` as the approval menu in review gates, task cards, and runbooks; each decision includes copyable reviewer reply text so agents do not infer permission to continue, release, or publish. The default console review gate, saved mission bundle README, concise handoff prompt, `--review-replies`, and saved `review-replies.txt` show those replies for first-open review. `missionControl.handoff.reviewGate`, `--handoff-json`, and saved `handoff.json` carry that same gate for transfer-only flows. The handoff prompt starts with `missionControl.resume.prompt`, so it carries the current cursor, runnable command or blocked input instruction, labeled unlocks or blockers, done criteria, ready proof, review stop condition, and reviewer replies in one copyable sentence; the normal console prints that same value as `Handoff Prompt` without requiring JSON or `--include-handoff`, `projscan start --handoff-prompt --intent "<goal>"` prints only that prompt for piping or copy/paste, and the Markdown runbook renders it as `## Handoff Prompt` so copied runbooks carry the same next-agent prompt. When a human just needs the runnable shell step, `projscan start --next-command --intent "<goal>"` prints only the current cursor command; when an MCP agent needs the callable equivalent, `projscan start --next-tool-call --intent "<goal>"` prints the current cursor tool call as compact JSON. Cite `missionControl.proofSummary` plus the runnable-only `missionControl.proofCommands` in broad handoff notes, and use `missionControl.handoff.readyProof.items` when resuming because it is the complete ordered remaining-proof queue; each item carries its CLI command and an optional MCP `toolCall`. `missionControl.handoff.readyProof.commands` and `toolCalls` remain convenient command-only and MCP-callable views. If the repo has `AGENTLOOP.md` or `agentloop.config.json`, start adds `npm exec agentloop -- status` to the coordination/proof queue; if `.agentflight/config.json` exists, it adds `npm exec agentflight -- verify`. These harness commands are emitted for agents, scripts, saved mission bundles, and `--proof-commands`; start reports them but does not execute them. MCP agents should use `missionControl.resume.toolCall` when present, use `missionControl.resume.inputBindings` to map unlocked placeholders to input steps, then call `missionControl.resume.followUps` as the next template calls; when they need one ordered sequence, follow `missionControl.resume.checklist`, whose `run_proof` rows include `tool` and `args` for MCP-callable proof steps. The normal console `Resume Checklist` and Markdown runbook checklist print callable rows inline as `(MCP: ...)` and mark unmapped proof rows as `(CLI only)`, so a copied runbook or default terminal run remains self-contained even outside the JSON payload. After the current action, prefer `missionControl.resume.remainingProofItems` for complete proof, using `remainingProofToolCalls` for the callable MCP subset without rerunning the current command. Humans can run the matching `command`; the normal console `Ready Proof` command list, normal console `Proof Queue`, and runbook `Proof queue` all use remaining proof so the current cursor command is not repeated, and each queued item shows either its MCP call or `CLI only`. Use `projscan_understand` and `projscan_preflight` when you need broader context or a safety gate. Use `projscan_workplan` when you need an ordered execution plan, `projscan_agent_brief` for a compact handoff, and `projscan_evidence_pack --pr-comment` when you need reviewer-facing proof. Deeper tools such as `doctor`, `hotspots`, `dataflow`, `review`, `bug-hunt`, `quality-scorecard`, `dogfood`, and `trial` are follow-up tools.
210
212
 
211
213
  For shortcut discovery, `projscan start --shortcuts --intent "<goal>"` prints the copyable command menu for the current mission, and `projscan start --shortcuts-json --intent "<goal>"` prints the same menu as JSON for agents and scripts. For shell copy/paste, `projscan start --mission-script --intent "<goal>"` prints a POSIX script that runs the current cursor command, then the remaining proof queue, then prints the review evidence commands. For MCP queue copy/paste, `projscan start --ready-tool-calls --intent "<goal>"` prints the current cursor call followed by remaining MCP-callable proof as compact JSON. For structured resume handoff, `projscan start --resume-json --intent "<goal>"` prints only `missionControl.resume`. For the complete transfer object, `projscan start --handoff-json --intent "<goal>"` prints only `missionControl.handoff`. For a file bundle, `projscan start --save-mission .projscan/mission --intent "<goal>"` writes `README.md`, `next-command.txt`, `next-tool-call.json`, `handoff-prompt.txt`, `resume-prompt.txt`, `task-card.md`, `review-gate.md`, `review-gate.json`, `review-policy.json`, `review-replies.txt`, the runbook, handoff JSON, resume JSON, `ready-tool-calls.json`, `shortcuts.json`, `mission.sh`, `status.sh`, `proof-logs/README.md`, `proof-logs/status.jsonl`, `proof-logs/run-report.md`, `proof-logs/summary.json`, proof commands, and manifest. Saved `mission.sh` writes current-command and proof-command output under `proof-logs/`, appends exit-code rows to `status.jsonl`, refreshes `run-report.md`, and writes `summary.json`, so reviewers and wrappers can scan pass/fail proof before opening raw logs. Bundle `status.sh` reads `summary.json` and uses exit codes `0`, `1`, and `2` for passed, failed, and not-ready states. For verification-only copy/paste, `projscan start --proof-commands --intent "<goal>"` prints the remaining ready proof commands one per line without the rest of the start report. For an ordered checklist without the full report, `projscan start --checklist --intent "<goal>"` prints only the resume checklist rows. For paste-ready PR, issue, or handoff notes, `projscan start --task-card --intent "<goal>"` prints the Markdown task card. MCP agents can read `missionControl.taskCard.markdown` when they need the same checklist without rendering it from `resume.checklist`. For stop-and-review notes, `projscan start --review-gate --intent "<goal>"` prints only `missionControl.reviewGate.markdown`, `projscan start --review-gate-json --intent "<goal>"` prints only the review gate JSON, `projscan start --review-policy --intent "<goal>"` prints only the review policy JSON, and `projscan start --review-replies --intent "<goal>"` prints only the copyable reviewer replies. For a full Markdown artifact, `projscan start --runbook --intent "<goal>"` prints the mission runbook. For post-run proof, `projscan mission-proof --mission .projscan/mission --format markdown` prints a paste-ready evidence report, while `--format json` keeps the same data machine-readable. Add `--list` to show saved mission bundles, status, update time, totals, and copyable resume/proof commands before choosing a target; add `--needs-attention` or `--mission-status failed` to focus that list. Add `--latest` to select the saved mission bundle with the newest `proof-logs/summary.json`. Add `--all` to include `.projscan/mission` and direct child bundles under `.projscan/missions/`. Add `--summary` when logs need one pass/fail line. Add `--require-passed` when a local script should fail unless every selected bundle passed. Add `--write reports/mission-proof.md` or `--write reports/mission-proof.json` when a reviewer, CI job, or next agent needs a saved local artifact. Run `projscan mission-proof --init-baseline manual-runs.json` before manual comparison if the team has not created the baseline file yet; use `--add-baseline-run manual-runs.json --id manual-1 --status passed --minutes-spent 25` to append measured manual runs without editing JSON. Run `--check-baseline manual-runs.json` before comparison when you want to validate the file without scanning mission bundles. Add `--format json` to baseline init, append, or check commands when a wrapper needs the written path, run count, added run, or totals. Baseline run IDs must be non-empty and unique; statuses must be `passed`, `failed`, `running`, `not_run`, or `unknown`; metric fields must be non-negative numbers.
212
214
 
@@ -235,8 +237,8 @@ npm run docs:demos
235
237
 
236
238
  When the agent has changes in flight (or is asked to review someone else's), the question shifts from "what's wrong globally" to "what changed, and does the change introduce risk?"
237
239
 
238
- - **`projscan_pr_diff` / `projscan pr-diff`** *(0.11+)* — structural (AST) diff between two refs. Returns added / removed / modified files with explicit lists of exports, imports, call sites, and ΔCC / Δfan-in. Not a text diff: surfaces the symbols that moved, not the whitespace.
239
- - **`projscan_review` / `projscan review`** *(0.13+)* — **the headline tool for this phase**. Composes `pr_diff` + per-file risk + new/expanded import cycles + risky function additions + dependency changes + optional `contractChanges` for export and package-entrypoint changes + `newTaintFlows`, hardened `newDataflowRisks`, compact `graphEvidence`, and a verdict (`ok` / `review` / `block`). One tool call answers the whole question.
240
+ - **`projscan_pr_diff` / `projscan pr-diff`** _(0.11+)_ — structural (AST) diff between two refs. Returns added / removed / modified files with explicit lists of exports, imports, call sites, and ΔCC / Δfan-in. Not a text diff: surfaces the symbols that moved, not the whitespace.
241
+ - **`projscan_review` / `projscan review`** _(0.13+)_ — **the headline tool for this phase**. Composes `pr_diff` + per-file risk + new/expanded import cycles + risky function additions + dependency changes + optional `contractChanges` for export and package-entrypoint changes + `newTaintFlows`, hardened `newDataflowRisks`, compact `graphEvidence`, and a verdict (`ok` / `review` / `block`). One tool call answers the whole question.
240
242
  - **`projscan_preflight --mode before_merge` / `projscan_preflight { mode: "before_merge" }`** — smaller merge gate over review, changed-file health, taint, dataflow, session, hotspot, plugin, supply-chain, and release-scale signals. `evidence.releaseScale` marks large platform-release sign-off when review blocks on scale/complexity rather than a concrete defect. Use it when the agent needs the decision before reading the full review payload.
241
243
 
242
244
  **Typical agent flow:** start with `projscan_review` for the verdict + summary; if it returns `review` or `block`, drill into the `riskyFunctions` and `newCycles` arrays for specifics.
@@ -245,18 +247,18 @@ When the agent has changes in flight (or is asked to review someone else's), the
245
247
 
246
248
  projscan diagnoses but does not run an LLM. The agent (the LLM) is what writes the fix. projscan's job in this phase is to package the issue context into something the agent can act on.
247
249
 
248
- - **`projscan_fix_suggest` / `projscan fix-suggest`** *(0.14+)* — given an issue id (or a `file` + `rule` pair), return a structured action prompt: headline, why it matters, where to change, one-paragraph instruction, optional suggested test. Hand-tuned templates for ~12 common issue families plus a severity-anchored generic fallback.
249
- - **`projscan_explain_issue` / `projscan explain-issue`** *(0.14+)* — deep dive: code excerpt around the location, related issues touching the same file, similar past commits via `git log --grep=<rule>`. Use when an agent wants more context than `doctor` gave.
250
+ - **`projscan_fix_suggest` / `projscan fix-suggest`** _(0.14+)_ — given an issue id (or a `file` + `rule` pair), return a structured action prompt: headline, why it matters, where to change, one-paragraph instruction, optional suggested test. Hand-tuned templates for ~12 common issue families plus a severity-anchored generic fallback.
251
+ - **`projscan_explain_issue` / `projscan explain-issue`** _(0.14+)_ — deep dive: code excerpt around the location, related issues touching the same file, similar past commits via `git log --grep=<rule>`. Use when an agent wants more context than `doctor` gave.
250
252
  - **`projscan fix`** — rule-based auto-fix (ESLint, Prettier, Vitest scaffolding, EditorConfig). Pre-dates the `fix_suggest` flow; useful for the no-LLM-required class of fixes.
251
253
 
252
254
  **Typical agent flow:** read an issue from `projscan_doctor`, call `projscan_fix_suggest` with its id, paste the `instruction` field into the agent's plan.
253
255
 
254
256
  ### 4. Reach — "what breaks if I change this?"
255
257
 
256
- Before the agent commits to a refactor (or accepts a name-rename suggestion), the question is: *who depends on this thing, transitively?*
258
+ Before the agent commits to a refactor (or accepts a name-rename suggestion), the question is: _who depends on this thing, transitively?_
257
259
 
258
- - **`projscan_impact` / `projscan impact`** *(0.15+)* — transitive blast-radius. File mode returns every file that transitively imports the target, ranked by BFS distance. Symbol mode returns the symbol's definition file(s), the files that directly call it (their callSites match), and the transitive importers of those callers. Cycle-safe; depth-bounded.
259
- - **`projscan_semantic_graph` (`query` mode) / `projscan semantic-graph`** — direct one-hop queries via `query: { direction, file?, symbol? }`: `imports`, `exports`, `importers`, `symbol_defs`, `package_importers`. Use when impact is overkill and you want a pin-point answer. Package wording such as `which files import package chalk`, `who uses lodash`, or `why do we depend on lodash` maps to `package_importers`. With no `query`, returns the full graph projection (file, function, package, and symbol context in one contract). *(Subsumes the former `projscan_graph`, removed in 4.0.)*
260
+ - **`projscan_impact` / `projscan impact`** _(0.15+)_ — transitive blast-radius. File mode returns every file that transitively imports the target, ranked by BFS distance. Symbol mode returns the symbol's definition file(s), the files that directly call it (their callSites match), and the transitive importers of those callers. Cycle-safe; depth-bounded.
261
+ - **`projscan_semantic_graph` (`query` mode) / `projscan semantic-graph`** — direct one-hop queries via `query: { direction, file?, symbol? }`: `imports`, `exports`, `importers`, `symbol_defs`, `package_importers`. Use when impact is overkill and you want a pin-point answer. Package wording such as `which files import package chalk`, `who uses lodash`, or `why do we depend on lodash` maps to `package_importers`. With no `query`, returns the full graph projection (file, function, package, and symbol context in one contract). _(Subsumes the former `projscan_graph`, removed in 4.0.)_
260
262
 
261
263
  **Typical agent flow:** before renaming or deleting an export, call `projscan_impact --symbol <name>` to see the dependent set; before deleting a file, call `projscan_impact <path>`. The truncated flag tells you whether the actual blast radius extends beyond what you saw.
262
264
 
@@ -264,12 +266,12 @@ Before the agent commits to a refactor (or accepts a name-rename suggestion), th
264
266
 
265
267
  Long agent sessions edit files repeatedly. Each edit could otherwise cost a full repo re-scan. The watch infrastructure keeps the graph current at low cost.
266
268
 
267
- - **`projscan watch`** *(0.16+)* — long-running CLI command. On file change, debounces 200ms then runs the incremental graph update + re-runs `doctor`, printing a one-line status. Uses `node:fs.watch`, no new runtime dep. Filters out `node_modules`, `.git`, build dirs, etc.
269
+ - **`projscan watch`** _(0.16+)_ — long-running CLI command. On file change, debounces 200ms then runs the incremental graph update + re-runs `doctor`, printing a one-line status. Uses `node:fs.watch`, no new runtime dep. Filters out `node_modules`, `.git`, build dirs, etc.
268
270
  - **`incrementallyUpdateGraph(graph, rootPath, changedPaths[])`** — the public API the watcher uses; exported so callers maintaining their own state can patch the graph in place after handling their own change events.
269
- - **`--format html`** *(0.16+, expanded in 2.x)* — for sharing review snapshots: `projscan analyze --format html > report.html` produces a self-contained HTML page suitable for posting as a PR comment or saving as a CI artifact. Renderers exist for `analyze`, `doctor`, `hotspots`, `coupling`, `pr-diff`, `review`, `impact`, and `coverage`.
270
- - **`projscan mcp --watch`** *(1.3+)* — when projscan runs as an MCP server with this flag, it pushes JSON-RPC `notifications/file_changed` events to the connected agent on every debounced batch. Long-session agents stop polling. The capability is advertised under `experimental.fileChanged` on the `initialize` response so clients can detect support.
271
- - **`projscan_session` MCP tool + `projscan session` CLI** *(1.4+)* — durable cross-invocation session. Auto-records every file path that any tool returned (`tool-result` source) and every fs-watch batch (`fs-watch` source), so multiple agent invocations against the same project share a "what's been touched here" view without re-running git. Idle window 1 hour by default; subactions: `current` / `touched` / `events` / `reset`. State lives at `.projscan-cache/session.json`.
272
- - **MCP resources** *(2.1+)* — `projscan://session/summary`, `projscan://handoff`, and `projscan://risk-now` expose the shared session as resource reads. Agents can pick up touched files, coordination conflicts, remaining risks, `coordinationHints`, and recommended next tool calls without spending a tool call on discovery. The hints separate current worktree checks from remembered session context and conflict resolution.
271
+ - **`--format html`** _(0.16+, expanded in 2.x)_ — for sharing review snapshots: `projscan analyze --format html > report.html` produces a self-contained HTML page suitable for posting as a PR comment or saving as a CI artifact. Renderers exist for `analyze`, `doctor`, `hotspots`, `coupling`, `pr-diff`, `review`, `impact`, and `coverage`.
272
+ - **`projscan mcp --watch`** _(1.3+)_ — when projscan runs as an MCP server with this flag, it pushes JSON-RPC `notifications/file_changed` events to the connected agent on every debounced batch. Long-session agents stop polling. The capability is advertised under `experimental.fileChanged` on the `initialize` response so clients can detect support.
273
+ - **`projscan_session` MCP tool + `projscan session` CLI** _(1.4+)_ — durable cross-invocation session. Auto-records every file path that any tool returned (`tool-result` source) and every fs-watch batch (`fs-watch` source), so multiple agent invocations against the same project share a "what's been touched here" view without re-running git. Idle window 1 hour by default; subactions: `current` / `touched` / `events` / `reset`. State lives at `.projscan-cache/session.json`.
274
+ - **MCP resources** _(2.1+)_ — `projscan://session/summary`, `projscan://handoff`, and `projscan://risk-now` expose the shared session as resource reads. Agents can pick up touched files, coordination conflicts, remaining risks, `coordinationHints`, and recommended next tool calls without spending a tool call on discovery. The hints separate current worktree checks from remembered session context and conflict resolution.
273
275
 
274
276
  **Typical workflow:** start `projscan watch` in a side terminal at the start of a long session; subsequent agent tool calls hit a warm graph cache. With multi-agent setups, every MCP tool call additionally records into the session, so a coordinator agent can ask `projscan_session { action: "touched" }` to see what its peers have touched.
275
277
 
@@ -286,6 +288,7 @@ projscan analyze
286
288
  The flagship command. Runs every detection module and produces the full project report.
287
289
 
288
290
  **What it does internally:**
291
+
289
292
  1. Builds the scan file set. In Git repos, projscan uses `git ls-files --cached --others --exclude-standard` by default, then applies built-in noise ignores and `.projscanrc` `ignore` globs. Non-Git folders fall back to the local file walker.
290
293
  2. Builds a language breakdown by mapping file extensions to language names
291
294
  3. Detects frameworks by inspecting `package.json` dependencies and config file presence
@@ -296,9 +299,9 @@ The flagship command. Runs every detection module and produces the full project
296
299
 
297
300
  **Options:**
298
301
 
299
- | Flag | Description |
300
- |------|-------------|
301
- | `--changed-only` | Only report issues on files changed vs base ref |
302
+ | Flag | Description |
303
+ | ------------------ | -------------------------------------------------------- |
304
+ | `--changed-only` | Only report issues on files changed vs base ref |
302
305
  | `--base-ref <ref>` | Git base ref for `--changed-only` (default: origin/main) |
303
306
 
304
307
  <img src="https://abhiyoheswaran.com/images/projscan/hero-poster.png" alt="npx projscan analyze: banner, scan progress, full project report" width="700">
@@ -315,14 +318,15 @@ Use this when you want a quick "is this project in good shape?" answer without t
315
318
 
316
319
  **Options:**
317
320
 
318
- | Flag | Description |
319
- |------|-------------|
320
- | `--changed-only` | Only report issues on files changed vs base ref |
321
+ | Flag | Description |
322
+ | ------------------ | -------------------------------------------------------- |
323
+ | `--changed-only` | Only report issues on files changed vs base ref |
321
324
  | `--base-ref <ref>` | Git base ref for `--changed-only` (default: origin/main) |
322
325
 
323
326
  <img src="npx%20projscan%20doctor.gif" alt="npx projscan doctor" width="700">
324
327
 
325
328
  **Severity levels:**
329
+
326
330
  - **error** (✖) - Problems that should be addressed immediately
327
331
  - **warning** (⚠) - Issues that affect code quality or maintainability
328
332
  - **info** (ℹ) - Suggestions for best practices
@@ -339,12 +343,13 @@ Ranks files by **risk** - a combination of git churn, complexity (lines of code)
339
343
 
340
344
  **Options:**
341
345
 
342
- | Flag | Description | Default |
343
- |------|-------------|---------|
344
- | `--limit <n>` | Number of hotspots to show | 10 (or `hotspots.limit` from `.projscanrc`) |
345
- | `--since <when>` | Git history window (e.g. `"6 months ago"`, `"2024-01-01"`) | `12 months ago` |
346
+ | Flag | Description | Default |
347
+ | ---------------- | ---------------------------------------------------------- | ------------------------------------------- |
348
+ | `--limit <n>` | Number of hotspots to show | 10 (or `hotspots.limit` from `.projscanrc`) |
349
+ | `--since <when>` | Git history window (e.g. `"6 months ago"`, `"2024-01-01"`) | `12 months ago` |
346
350
 
347
351
  **What you get per file:**
352
+
348
353
  - `riskScore` - combined score (0–100)
349
354
  - `churn` - number of commits touching the file in the window
350
355
  - `distinctAuthors` - how many people have touched it
@@ -379,14 +384,14 @@ import a package.
379
384
 
380
385
  **Options:**
381
386
 
382
- | Flag | Description | Default |
383
- |------|-------------|---------|
384
- | `--max-nodes <n>` | Maximum nodes to return | 10000 |
385
- | `--max-edges <n>` | Maximum edges to return | 25000 |
387
+ | Flag | Description | Default |
388
+ | --------------------- | ---------------------------------------------------------------------------------------- | ---------- |
389
+ | `--max-nodes <n>` | Maximum nodes to return | 10000 |
390
+ | `--max-edges <n>` | Maximum edges to return | 25000 |
386
391
  | `--query <direction>` | Targeted query: `imports`, `exports`, `importers`, `symbol_defs`, or `package_importers` | full graph |
387
- | `--file <path>` | Repo-relative file for `imports`, `exports`, or `importers` | - |
388
- | `--symbol <name>` | Symbol/package for `symbol_defs` or `package_importers` | - |
389
- | `--limit <n>` | Maximum targeted query entries | 50 |
392
+ | `--file <path>` | Repo-relative file for `imports`, `exports`, or `importers` | - |
393
+ | `--symbol <name>` | Symbol/package for `symbol_defs` or `package_importers` | - |
394
+ | `--limit <n>` | Maximum targeted query entries | 50 |
390
395
 
391
396
  ### understand
392
397
 
@@ -402,21 +407,21 @@ Repo understanding for engineers before they edit. The command returns a cited r
402
407
 
403
408
  Views:
404
409
 
405
- | View | Use it for |
406
- |------|------------|
407
- | `map` | Orient around entrypoints, package boundaries, read-first files, risks, and unknowns |
408
- | `flow` | Trace runtime paths and side-effect sinks through graph-backed evidence |
409
- | `contracts` | Inspect public exports, config/env contracts, and likely breaking-change risks |
410
- | `change` | Tie an intent to blast radius, first safe edit, owner state, rollback, and verification commands |
411
- | `verify` | Build minimal, focused, and full proof tiers plus direct-test gap evidence |
410
+ | View | Use it for |
411
+ | ----------- | ------------------------------------------------------------------------------------------------ |
412
+ | `map` | Orient around entrypoints, package boundaries, read-first files, risks, and unknowns |
413
+ | `flow` | Trace runtime paths and side-effect sinks through graph-backed evidence |
414
+ | `contracts` | Inspect public exports, config/env contracts, and likely breaking-change risks |
415
+ | `change` | Tie an intent to blast radius, first safe edit, owner state, rollback, and verification commands |
416
+ | `verify` | Build minimal, focused, and full proof tiers plus direct-test gap evidence |
412
417
 
413
418
  **Options:**
414
419
 
415
- | Flag | Description | Default |
416
- |------|-------------|---------|
417
- | `--view <view>` | `map`, `flow`, `contracts`, `change`, or `verify` | `map` |
418
- | `--intent <text>` | Planned change or question for change-readiness output | none |
419
- | `--max-items <n>` | Maximum items per section | 8 |
420
+ | Flag | Description | Default |
421
+ | ----------------- | ------------------------------------------------------ | ------- |
422
+ | `--view <view>` | `map`, `flow`, `contracts`, `change`, or `verify` | `map` |
423
+ | `--intent <text>` | Planned change or question for change-readiness output | none |
424
+ | `--max-items <n>` | Maximum items per section | 8 |
420
425
 
421
426
  ### dataflow
422
427
 
@@ -434,13 +439,13 @@ For release hardening, `npm run check:graph-corpus` compares bundled fixture met
434
439
 
435
440
  **Options:**
436
441
 
437
- | Flag | Description | Default |
438
- |------|-------------|---------|
439
- | `--source <name...>` | Add custom source identifiers | Built-ins + config |
440
- | `--sink <name...>` | Add custom sink identifiers | Built-ins + config |
441
- | `--max-risks <n>` | Maximum risks to return | 50 |
442
- | `--include-tests` | Include risks that touch test files | false |
443
- | `--include-broad-file-io` | Include broad default readFile/writeFile-style risks | false |
442
+ | Flag | Description | Default |
443
+ | ------------------------- | ---------------------------------------------------- | ------------------ |
444
+ | `--source <name...>` | Add custom source identifiers | Built-ins + config |
445
+ | `--sink <name...>` | Add custom sink identifiers | Built-ins + config |
446
+ | `--max-risks <n>` | Maximum risks to return | 50 |
447
+ | `--include-tests` | Include risks that touch test files | false |
448
+ | `--include-broad-file-io` | Include broad default readFile/writeFile-style risks | false |
444
449
 
445
450
  ### search
446
451
 
@@ -457,14 +462,15 @@ BM25-ranked search across content, symbol names, and path tokens. No embeddings,
457
462
 
458
463
  **Scopes:**
459
464
 
460
- | Scope | What it matches | Ranking |
461
- |-------|-----------------|---------|
462
- | `auto` (default) | Content, with symbol + path boost | BM25 + symbol boost × 2.0 + path boost × 0.5 |
463
- | `content` | Same as `auto` | BM25 |
464
- | `symbols` | Names of exported functions/classes/types/etc. | Exact → prefix → substring |
465
- | `files` | Relative path substring | Path order |
465
+ | Scope | What it matches | Ranking |
466
+ | ---------------- | ---------------------------------------------- | -------------------------------------------- |
467
+ | `auto` (default) | Content, with symbol + path boost | BM25 + symbol boost × 2.0 + path boost × 0.5 |
468
+ | `content` | Same as `auto` | BM25 |
469
+ | `symbols` | Names of exported functions/classes/types/etc. | Exact → prefix → substring |
470
+ | `files` | Relative path substring | Path order |
466
471
 
467
472
  **Query handling:**
473
+
468
474
  - Tokens are split on camelCase, snake_case, and digits. `userAuthToken` indexes as `user`, `auth`, `token`.
469
475
  - Light stemming (trailing `-s`, `-ing`, `-ed` stripped).
470
476
  - Stopwords and TypeScript keywords filtered (`the`, `function`, `class`, `export`, …).
@@ -473,7 +479,8 @@ BM25-ranked search across content, symbol names, and path tokens. No embeddings,
473
479
  **Output includes:** file path, line number, a one-line excerpt centered on the first matching line, the match score, and which tokens matched.
474
480
 
475
481
  **Limitations:**
476
- - No real semantic understanding by default. Searching for *"payment processing"* won't find a file that implements Stripe under the name `charge()`. True semantic search (local embeddings) shipped in 0.9.0 as an opt-in peer dep - install `@xenova/transformers` and pass `--mode semantic` (or `--mode hybrid` for BM25 + semantic via reciprocal rank fusion).
482
+
483
+ - No real semantic understanding by default. Searching for _"payment processing"_ won't find a file that implements Stripe under the name `charge()`. True semantic search (local embeddings) shipped in 0.9.0 as an opt-in peer dep - install `@xenova/transformers` and pass `--mode semantic` (or `--mode hybrid` for BM25 + semantic via reciprocal rank fusion).
477
484
  - Index is rebuilt on every run (fast - the AST is already parsed from the code-graph cache).
478
485
 
479
486
  ### file
@@ -490,7 +497,7 @@ Per-file drill-down. Combines everything ProjScan knows about a file into one vi
490
497
  - **Related issues** - every open issue whose `locations` reference the file
491
498
  - **Inline smells** - large files, `console.log`, TODO/FIXME, `any` types
492
499
 
493
- Natural follow-up to `projscan hotspots` - once hotspots tells you *which* file to look at, `file` tells you *what* to do about it.
500
+ Natural follow-up to `projscan hotspots` - once hotspots tells you _which_ file to look at, `file` tells you _what_ to do about it.
494
501
 
495
502
  ### ci
496
503
 
@@ -502,11 +509,11 @@ A CI-pipeline-friendly health gate. Runs the full health check and exits with co
502
509
 
503
510
  **Options:**
504
511
 
505
- | Flag | Description | Default |
506
- |------|-------------|---------|
507
- | `--min-score <n>` | Minimum passing score (0–100) | `minScore` from `.projscanrc`, else 70 |
508
- | `--changed-only` | Gate only on issues in files changed vs base ref | off |
509
- | `--base-ref <ref>` | Git base ref for `--changed-only` | auto (origin/main → origin/master → main → master → HEAD~1) |
512
+ | Flag | Description | Default |
513
+ | ------------------ | ------------------------------------------------ | ----------------------------------------------------------- |
514
+ | `--min-score <n>` | Minimum passing score (0–100) | `minScore` from `.projscanrc`, else 70 |
515
+ | `--changed-only` | Gate only on issues in files changed vs base ref | off |
516
+ | `--base-ref <ref>` | Git base ref for `--changed-only` | auto (origin/main → origin/master → main → master → HEAD~1) |
510
517
 
511
518
  **Example:**
512
519
 
@@ -519,6 +526,7 @@ projscan: B (82/100) - 0 errors, 2 warnings, 1 info - PASS (threshold: 80)
519
526
  <img src="npx%20projscan%20ci%20--min-score%2070.gif" alt="npx projscan ci" width="700">
520
527
 
521
528
  **Exit codes:**
529
+
522
530
  - `0` - Score meets or exceeds the threshold
523
531
  - `1` - Score is below the threshold
524
532
 
@@ -553,9 +561,9 @@ Compare your project's current health and hotspots against a saved baseline. Use
553
561
 
554
562
  **Options:**
555
563
 
556
- | Flag | Description |
557
- |------|-------------|
558
- | `--save-baseline` | Save current health + top hotspots as the baseline |
564
+ | Flag | Description |
565
+ | ------------------- | ---------------------------------------------------------- |
566
+ | `--save-baseline` | Save current health + top hotspots as the baseline |
559
567
  | `--baseline <path>` | Path to baseline file (default: `.projscan-baseline.json`) |
560
568
 
561
569
  **Workflow:**
@@ -593,12 +601,12 @@ projscan fix -y
593
601
 
594
602
  **Available fixes:**
595
603
 
596
- | Fix | What it creates | What it installs |
597
- |-----|----------------|-----------------|
598
- | ESLint | `eslint.config.js` (with TypeScript support if TS is detected) | `eslint`, `@eslint/js`, optionally `typescript-eslint` |
599
- | Prettier | `.prettierrc` with sensible defaults | `prettier` |
600
- | Test framework | `vitest.config.ts` + sample test file, adds `test` script to package.json | `vitest` |
601
- | EditorConfig | `.editorconfig` (UTF-8, LF, 2-space indent, trim trailing whitespace) | Nothing |
604
+ | Fix | What it creates | What it installs |
605
+ | -------------- | ------------------------------------------------------------------------- | ------------------------------------------------------ |
606
+ | ESLint | `eslint.config.js` (with TypeScript support if TS is detected) | `eslint`, `@eslint/js`, optionally `typescript-eslint` |
607
+ | Prettier | `.prettierrc` with sensible defaults | `prettier` |
608
+ | Test framework | `vitest.config.ts` + sample test file, adds `test` script to package.json | `vitest` |
609
+ | EditorConfig | `.editorconfig` (UTF-8, LF, 2-space indent, trim trailing whitespace) | Nothing |
602
610
 
603
611
  ### diagram
604
612
 
@@ -639,6 +647,7 @@ projscan outdated
639
647
  Offline drift check - compares the version declared in `package.json` against the version installed under `node_modules/<pkg>/package.json`. Classifies each package as `patch`, `minor`, `major`, `same`, or `unknown` drift. Does **not** hit the npm registry.
640
648
 
641
649
  **Output fields per package:**
650
+
642
651
  - `declared` - the range in `package.json` (e.g., `^1.2.3`)
643
652
  - `installed` - the concrete version in `node_modules`, or `null` if not installed
644
653
  - `latest` - same as `installed` in this offline drift check
@@ -669,9 +678,9 @@ Each finding becomes a SARIF result with `ruleId: audit-<pkg>`, severity mapped
669
678
 
670
679
  **Options:**
671
680
 
672
- | Flag | Description | Default |
673
- |------|-------------|---------|
674
- | `--timeout <ms>` | Override npm audit timeout | 60000 |
681
+ | Flag | Description | Default |
682
+ | ---------------- | -------------------------- | ------- |
683
+ | `--timeout <ms>` | Override npm audit timeout | 60000 |
675
684
 
676
685
  ### upgrade
677
686
 
@@ -682,6 +691,7 @@ projscan upgrade <package>
682
691
  Preview the impact of upgrading a package. The default path is fully offline; pass `--check-registry` when you explicitly want npm registry lookup for the current latest version.
683
692
 
684
693
  **What you get:**
694
+
685
695
  - Drift classification (`patch` / `minor` / `major`)
686
696
  - Breaking-change markers found in the CHANGELOG: scans for `BREAKING CHANGE`, `deprecated`, `removed support`, `no longer supported`, and section headers containing "breaking"
687
697
  - CHANGELOG excerpt sliced to the relevant version range (read from `node_modules/<pkg>/CHANGELOG.md`)
@@ -704,6 +714,7 @@ $ projscan upgrade react --format markdown
704
714
  ```
705
715
 
706
716
  **Limitations:**
717
+
707
718
  - Reads the CHANGELOG that npm already placed in `node_modules/`. If the package author doesn't ship one, you'll see "No local CHANGELOG found."
708
719
  - Without `--check-registry`, works with what's **installed** and reports `latestSource: "installed"`. With `--check-registry`, npm registry lookup is attempted and failures fall back to the installed version with `registryError`.
709
720
 
@@ -716,11 +727,13 @@ projscan coverage
716
727
  Joins test coverage with the hotspot ranking and produces a list sorted by "risk × uncovered fraction" - the files that most deserve tests.
717
728
 
718
729
  **Supported formats** (auto-detected in this order):
730
+
719
731
  - `coverage/lcov.info` - lcov format (Vitest, Jest, c8)
720
732
  - `coverage/coverage-final.json` - Istanbul per-file detail
721
733
  - `coverage/coverage-summary.json` - Istanbul summary
722
734
 
723
735
  **Output fields per entry:**
736
+
724
737
  - `relativePath` - file path
725
738
  - `riskScore` - the file's hotspot risk
726
739
  - `coverage` - line coverage %, or `null` if the file isn't in the coverage report
@@ -729,8 +742,8 @@ Joins test coverage with the hotspot ranking and produces a list sorted by "risk
729
742
 
730
743
  **Options:**
731
744
 
732
- | Flag | Description | Default |
733
- |------|-------------|---------|
745
+ | Flag | Description | Default |
746
+ | ------------- | --------------------------- | ------------ |
734
747
  | `--limit <n>` | Number of entries to return | 30 (max 200) |
735
748
 
736
749
  **How it feeds into `hotspots`:** when any coverage file exists, `projscan hotspots` automatically passes it into the risk calculator. Uncovered churning files get a score bump and a `low coverage (X%)` reason tag. No coverage file? Hotspots behaves exactly as before.
@@ -758,7 +771,7 @@ With `--watch`, the server starts an in-process file watcher and emits a JSON-RP
758
771
 
759
772
  See [MCP Server for AI Agents](#mcp-server-for-ai-agents).
760
773
 
761
- ### session *(1.4+)*
774
+ ### session _(1.4+)_
762
775
 
763
776
  ```bash
764
777
  projscan session # current session summary
@@ -829,22 +842,23 @@ Every `projscan doctor` and `projscan badge` run calculates a health score from
829
842
  **Scoring:**
830
843
 
831
844
  | Severity | Deduction per issue |
832
- |----------|-------------------|
833
- | Error | -20 points |
834
- | Warning | -10 points |
835
- | Info | -3 points |
845
+ | -------- | ------------------- |
846
+ | Error | -20 points |
847
+ | Warning | -10 points |
848
+ | Info | -3 points |
836
849
 
837
850
  **Grade thresholds:**
838
851
 
839
- | Grade | Score Range | Meaning |
840
- |-------|-------------|---------|
841
- | A | 90–100 | Excellent - project follows best practices |
842
- | B | 80–89 | Good - minor improvements possible |
843
- | C | 70–79 | Fair - several issues to address |
844
- | D | 60–69 | Poor - significant issues found |
845
- | F | < 60 | Critical - major issues need attention |
852
+ | Grade | Score Range | Meaning |
853
+ | ----- | ----------- | ------------------------------------------ |
854
+ | A | 90–100 | Excellent - project follows best practices |
855
+ | B | 80–89 | Good - minor improvements possible |
856
+ | C | 70–79 | Fair - several issues to address |
857
+ | D | 60–69 | Poor - significant issues found |
858
+ | F | < 60 | Critical - major issues need attention |
846
859
 
847
860
  The score appears in all output formats:
861
+
848
862
  - **Console**: Shown at the top of the doctor report
849
863
  - **JSON**: Included as `health.score` and `health.grade` fields
850
864
  - **Markdown**: Shown as a heading with an auto-generated shields.io badge
@@ -898,6 +912,7 @@ projscan ci --format sarif > projscan.sarif
898
912
  ```
899
913
 
900
914
  Supported on `analyze`, `audit`, `ci`, `doctor`, and `outdated`. Each issue is emitted as a SARIF `result` with:
915
+
901
916
  - `ruleId` - stable rule identifier (e.g., `hardcoded-secret`, `missing-prettier`)
902
917
  - `level` - `error`, `warning`, or `note` (mapped from projscan severity)
903
918
  - `message.text` - the issue description
@@ -945,18 +960,18 @@ ProjScan loads a project-wide config from one of:
945
960
 
946
961
  ### Fields
947
962
 
948
- | Field | Type | Effect |
949
- |-------|------|--------|
950
- | `minScore` | number (0–100) | Default threshold for `projscan ci`. Clamped to 0–100. |
951
- | `baseRef` | string | Default base ref for `--changed-only`. |
952
- | `ignore` | string[] | Extra glob patterns added to the built-in ignore list (`node_modules`, `.git`, `dist`, `build`, `coverage`, `.next`, `.nuxt`, `.cache`, `.turbo`, `.output`). |
953
- | `scan.includeIgnored` | boolean | Explicitly include files hidden by Git ignore rules. Default `false`. |
954
- | `scan.scanEnvValues` | boolean | Explicitly read `.env*` contents during secret-pattern checks. Default `false`; `.env` files are path-only. |
955
- | `scan.offline` | boolean | Block projscan network-capable features: telemetry sending, `audit`, registry checks, and optional semantic model loading. Default `false`. |
956
- | `disableRules` | string[] | Silence rules by id. Exact match (`missing-prettier`) or wildcard prefix (`large-*`). |
957
- | `severityOverrides` | `Record<string, 'info' \| 'warning' \| 'error'>` | Remap a rule's severity. Useful for downgrading project-specific false positives without disabling them. |
958
- | `hotspots.limit` | number (1–100) | Default limit for `projscan hotspots`. |
959
- | `hotspots.since` | string | Default git history window for `projscan hotspots`. |
963
+ | Field | Type | Effect |
964
+ | --------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
965
+ | `minScore` | number (0–100) | Default threshold for `projscan ci`. Clamped to 0–100. |
966
+ | `baseRef` | string | Default base ref for `--changed-only`. |
967
+ | `ignore` | string[] | Extra glob patterns added to the built-in ignore list (`node_modules`, `.git`, `dist`, `build`, `coverage`, `.next`, `.nuxt`, `.cache`, `.turbo`, `.output`). |
968
+ | `scan.includeIgnored` | boolean | Explicitly include files hidden by Git ignore rules. Default `false`. |
969
+ | `scan.scanEnvValues` | boolean | Explicitly read `.env*` contents during secret-pattern checks. Default `false`; `.env` files are path-only. |
970
+ | `scan.offline` | boolean | Block projscan network-capable features: telemetry sending, `audit`, registry checks, and optional semantic model loading. Default `false`. |
971
+ | `disableRules` | string[] | Silence rules by id. Exact match (`missing-prettier`) or wildcard prefix (`large-*`). |
972
+ | `severityOverrides` | `Record<string, 'info' \| 'warning' \| 'error'>` | Remap a rule's severity. Useful for downgrading project-specific false positives without disabling them. |
973
+ | `hotspots.limit` | number (1–100) | Default limit for `projscan hotspots`. |
974
+ | `hotspots.since` | string | Default git history window for `projscan hotspots`. |
960
975
 
961
976
  Invalid JSON in a discovered config file is a hard error - projscan exits rather than silently ignoring it.
962
977
 
@@ -974,7 +989,7 @@ If you prefer to keep everything in `package.json`:
974
989
  }
975
990
  ```
976
991
 
977
- ### Monorepo: cross-package import policy *(0.14+)*
992
+ ### Monorepo: cross-package import policy _(0.14+)_
978
993
 
979
994
  In a monorepo, you can declare which packages may import which. Violations surface as `cross-package-violation-N` issues in `projscan_doctor` and on the CLI. The analyzer is **off by default**; adding any rule turns it on for the matching `from` package.
980
995
 
@@ -1035,19 +1050,19 @@ Example GitHub Actions snippet:
1035
1050
 
1036
1051
  ## Global Options
1037
1052
 
1038
- | Option | Description |
1039
- |--------|-------------|
1040
- | `--format <type>` | Output format: `console` (default), `json`, `markdown`, `sarif`, `html` (command-dependent) |
1041
- | `--config <path>` | Path to a `.projscanrc` config file |
1042
- | `--include-ignored` | Explicitly include files hidden by Git ignore rules |
1043
- | `--scan-env-values` | Explicitly read `.env*` contents during secret checks |
1044
- | `--offline` | Block projscan network-capable features for this run |
1045
- | `--changed-only` | Scope to files changed vs base ref (applies to `analyze`, `doctor`, `ci`) |
1046
- | `--base-ref <ref>` | Git base ref for `--changed-only` (default: origin/main) |
1047
- | `--verbose` | Show debug-level logging - useful for diagnosing scan issues |
1048
- | `--quiet` | Suppress all non-essential output (spinners, status messages) |
1049
- | `-V, --version` | Print the version number |
1050
- | `-h, --help` | Print help for any command |
1053
+ | Option | Description |
1054
+ | ------------------- | ------------------------------------------------------------------------------------------- |
1055
+ | `--format <type>` | Output format: `console` (default), `json`, `markdown`, `sarif`, `html` (command-dependent) |
1056
+ | `--config <path>` | Path to a `.projscanrc` config file |
1057
+ | `--include-ignored` | Explicitly include files hidden by Git ignore rules |
1058
+ | `--scan-env-values` | Explicitly read `.env*` contents during secret checks |
1059
+ | `--offline` | Block projscan network-capable features for this run |
1060
+ | `--changed-only` | Scope to files changed vs base ref (applies to `analyze`, `doctor`, `ci`) |
1061
+ | `--base-ref <ref>` | Git base ref for `--changed-only` (default: origin/main) |
1062
+ | `--verbose` | Show debug-level logging - useful for diagnosing scan issues |
1063
+ | `--quiet` | Suppress all non-essential output (spinners, status messages) |
1064
+ | `-V, --version` | Print the version number |
1065
+ | `-h, --help` | Print help for any command |
1051
1066
 
1052
1067
  **Per-command help:**
1053
1068
 
@@ -1085,31 +1100,37 @@ Each detection has a **confidence level** (high, medium, low) and a **category**
1085
1100
  ProjScan ships with six analyzer modules:
1086
1101
 
1087
1102
  #### 1. ESLint Check
1103
+
1088
1104
  - Looks for `.eslintrc.*`, `eslint.config.*`, or `eslintConfig` in package.json
1089
1105
  - If missing: warning with auto-fix available
1090
1106
 
1091
1107
  #### 2. Prettier Check
1108
+
1092
1109
  - Looks for `.prettierrc`, `.prettierrc.*`, `prettier.config.*`, or `prettier` in package.json
1093
1110
  - If missing: warning with auto-fix available
1094
1111
 
1095
1112
  #### 3. Test Check
1113
+
1096
1114
  - Looks for test frameworks in devDependencies (vitest, jest, mocha, etc.)
1097
1115
  - Looks for test files (`*.test.*`, `*.spec.*`, `__tests__/`)
1098
1116
  - If no framework: warning with auto-fix available
1099
1117
  - If framework exists but zero test files: separate warning
1100
1118
 
1101
1119
  #### 4. Architecture Check
1120
+
1102
1121
  - **Large utility directories**: warns if `utils/`, `helpers/`, or `lib/` contains 10+ files (issue anchored to the directory path)
1103
1122
  - **Missing .editorconfig**: info with auto-fix available
1104
1123
  - **Missing/empty README**: warning / info
1105
1124
 
1106
1125
  #### 5. Dependency Risk Check
1126
+
1107
1127
  - Warns if production dependencies exceed 50
1108
1128
  - Errors if total dependencies exceed 100
1109
1129
  - Flags `*` or `latest` version ranges
1110
1130
  - Warns if no lock file is present
1111
1131
 
1112
1132
  #### 6. Security Check
1133
+
1113
1134
  - **Committed `.env` files**: Flags `.env`, `.env.local`, `.env.production`, etc. (but not `.env.example`, `.env.sample`, `.env.template`) - location anchored to the file
1114
1135
  - **Private key files**: Detects `.pem`, `.key`, `id_rsa`, `id_ed25519`, `.p12`, `.pfx` files
1115
1136
  - **Hardcoded secrets**: Scans file contents (files under 512KB) for:
@@ -1118,7 +1139,7 @@ ProjScan ships with six analyzer modules:
1118
1139
  - Slack tokens (`xoxb-...`, `xoxp-...`)
1119
1140
  - Generic patterns (`password=`, `secret=`, `api_key=` with quoted values)
1120
1141
  - PEM private key headers
1121
- Each finding carries the exact **line number** of the match, which SARIF and GitHub Code Scanning use for inline PR annotations.
1142
+ Each finding carries the exact **line number** of the match, which SARIF and GitHub Code Scanning use for inline PR annotations.
1122
1143
  - **Missing `.gitignore` entries**: Warns if `.env` is not in `.gitignore`
1123
1144
  - **Path-only `.env` handling**: Tracked `.env*` files are flagged by filename, but their values are not read unless `--scan-env-values` or `scan.scanEnvValues: true` is set
1124
1145
 
@@ -1142,11 +1163,13 @@ The fix system is intentionally conservative. It only creates configuration file
1142
1163
  ### Fix details
1143
1164
 
1144
1165
  **ESLint fix:**
1166
+
1145
1167
  - Creates `eslint.config.js` using the flat config format (ESLint v9+)
1146
1168
  - If TypeScript files are detected, includes `typescript-eslint` plugin
1147
1169
  - Installs `eslint` and `@eslint/js` via the detected package manager
1148
1170
 
1149
1171
  **Prettier fix:**
1172
+
1150
1173
  - Creates `.prettierrc` with these defaults:
1151
1174
  ```json
1152
1175
  {
@@ -1160,12 +1183,14 @@ The fix system is intentionally conservative. It only creates configuration file
1160
1183
  - Installs `prettier`
1161
1184
 
1162
1185
  **Test framework fix:**
1186
+
1163
1187
  - Creates `vitest.config.ts`
1164
1188
  - Creates a sample test file at `tests/example.test.ts`
1165
1189
  - Adds `"test": "vitest run"` to package.json scripts (if not already present)
1166
1190
  - Installs `vitest`
1167
1191
 
1168
1192
  **EditorConfig fix:**
1193
+
1169
1194
  - Creates `.editorconfig`
1170
1195
  - Installs nothing - EditorConfig is handled by editor plugins
1171
1196
 
@@ -1189,6 +1214,7 @@ This is heuristic-based and works best with conventional project structures. Pro
1189
1214
  The `explain` command performs regex-based static analysis. It does not execute your code or make network calls.
1190
1215
 
1191
1216
  **Import detection** handles:
1217
+
1192
1218
  - ES modules: `import { foo } from 'bar'`
1193
1219
  - Default imports: `import foo from 'bar'`
1194
1220
  - Namespace imports: `import * as foo from 'bar'`
@@ -1196,11 +1222,13 @@ The `explain` command performs regex-based static analysis. It does not execute
1196
1222
  - CommonJS: `const foo = require('bar')`
1197
1223
 
1198
1224
  **Export detection** handles:
1225
+
1199
1226
  - Named exports: `export function`, `export class`, `export const`
1200
1227
  - Type exports: `export interface`, `export type`
1201
1228
  - Default exports: `export default`
1202
1229
 
1203
1230
  **Purpose inference** is based on file name and directory conventions. For example:
1231
+
1204
1232
  - Files named `*.test.*` or `*.spec.*` → "Test file"
1205
1233
  - Files in `routes/` → "Route definitions"
1206
1234
  - Files named `index.ts` → "Module entry point"
@@ -1212,15 +1240,16 @@ The `explain` command performs regex-based static analysis. It does not execute
1212
1240
 
1213
1241
  The `hotspots` command reads `git log` to build a per-file risk picture. The risk score combines five signals:
1214
1242
 
1215
- | Signal | Weight | Intuition |
1216
- |--------|--------|-----------|
1217
- | Churn | 0.40 | Files that change often are more likely to harbor bugs |
1218
- | Complexity (AST CC) | 0.30 | Files with more decision points are harder to reason about. **AST-derived McCabe cyclomatic complexity for JS/TS, Python, Go, Java, Ruby, Rust, PHP, and C#; falls back to LOC for non-AST languages.** |
1219
- | Issue density | 0.20 | Files that already have open issues need help |
1220
- | Recency | 0.10 | Recently touched hot files deserve attention first |
1221
- | Bus factor | penalty tag | Single-author + high churn = organizational risk |
1243
+ | Signal | Weight | Intuition |
1244
+ | ------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1245
+ | Churn | 0.40 | Files that change often are more likely to harbor bugs |
1246
+ | Complexity (AST CC) | 0.30 | Files with more decision points are harder to reason about. **AST-derived McCabe cyclomatic complexity for JS/TS, Python, Go, Java, Ruby, Rust, PHP, and C#; falls back to LOC for non-AST languages.** |
1247
+ | Issue density | 0.20 | Files that already have open issues need help |
1248
+ | Recency | 0.10 | Recently touched hot files deserve attention first |
1249
+ | Bus factor | penalty tag | Single-author + high churn = organizational risk |
1222
1250
 
1223
1251
  **Ownership signals:**
1252
+
1224
1253
  - `primaryAuthor` - the top committer by share
1225
1254
  - `primaryAuthorShare` - fraction of commits (0–1)
1226
1255
  - `topAuthors` - ranked list
@@ -1229,6 +1258,7 @@ The `hotspots` command reads `git log` to build a per-file risk picture. The ris
1229
1258
  **Bus-factor-one files get a score penalty and a `bus-factor-one` reason tag** - they show up higher in the ranking because if that one author leaves, the knowledge is gone.
1230
1259
 
1231
1260
  **What "hotspots" can't do:**
1261
+
1232
1262
  - It's a heuristic, not a proof. Low-risk files may still have bugs.
1233
1263
  - It weights LOC as a proxy for complexity; a clean 1,000-line file may rank higher than it deserves.
1234
1264
  - It has no visibility into logical coupling - two small files that change together still look independent.
@@ -1243,16 +1273,17 @@ The `hotspots` command reads `git log` to build a per-file risk picture. The ris
1243
1273
 
1244
1274
  **Core tools include:**
1245
1275
 
1246
- *Structural / agent-native:*
1276
+ _Structural / agent-native:_
1277
+
1247
1278
  - `projscan_start` — first-60-seconds repo orientation with setup diagnostics, recommended workflow, top risks, adoption gaps, and next commands.
1248
- - `projscan_semantic_graph` — the code graph, two ways. With no `query`: the stable v3 semantic graph (file/function/package/symbol nodes and normalized structural edges). With `query: { direction, file?, symbol? }`: a targeted structural query (`imports`, `exports`, `importers`, `symbol_defs`, `package_importers`) in milliseconds on a warm cache. *(Subsumes the former `projscan_graph`, removed in 4.0.)*
1279
+ - `projscan_semantic_graph` — the code graph, two ways. With no `query`: the stable v3 semantic graph (file/function/package/symbol nodes and normalized structural edges). With `query: { direction, file?, symbol? }`: a targeted structural query (`imports`, `exports`, `importers`, `symbol_defs`, `package_importers`) in milliseconds on a warm cache. _(Subsumes the former `projscan_graph`, removed in 4.0.)_
1249
1280
  - `projscan_dataflow` — direct, propagated, and bridge source-to-sink dataflow risks over the function graph.
1250
1281
  - `projscan_search` — BM25-ranked search. Scopes: `auto` / `content` (ranked content + symbol + path boosts, line excerpts), `symbols` (exported names), `files` (path substring). Optional semantic mode + sub-file chunking with the `@xenova/transformers` peer dep.
1251
1282
  - `projscan_coupling` — per-file fan-in / fan-out / instability + Tarjan circular-import cycles.
1252
1283
  - `projscan_pr_diff` — structural (AST) diff between two refs. Returns added / removed / modified files with explicit lists of exports, imports, call sites, and ΔCC / Δfan-in.
1253
1284
  - `projscan_review` — one-call PR review composing `pr_diff` + per-changed-file risk + new/expanded cycles + risky function additions + dependency changes + a verdict (`ok` / `review` / `block`).
1254
1285
  - `projscan_workplan` — prioritized agent execution plan with evidence, suggested tools, verification commands, coordination context, and handoff text.
1255
- - `projscan_bug_hunt` — prioritized bug-hunt fix queue with per-target verification.
1286
+ - `projscan_bug_hunt` — prioritized bug-hunt action queue with per-action verification.
1256
1287
  - `projscan_agent_brief` — compact next-agent context packet with focus items, guardrails, repo context, and suggested next actions.
1257
1288
  - `projscan_quality_scorecard` — dimensioned quality view with top risks and verification commands.
1258
1289
  - `projscan_adoption` — adoption helper for MCP client snippets, MCP setup doctor, agent workflow recipes, and first-run diagnostics.
@@ -1263,7 +1294,8 @@ The `hotspots` command reads `git log` to build a per-file risk picture. The ris
1263
1294
  - `projscan_explain_issue` — deep dive on one issue: code excerpt, related issues, similar past commits via `git log --grep`, plus the structured FixSuggestion.
1264
1295
  - `projscan_impact` — transitive blast-radius for a file or symbol. BFS over reverse imports + symbol callsites. Cycle-safe; depth-bounded.
1265
1296
 
1266
- *Analysis:*
1297
+ _Analysis:_
1298
+
1267
1299
  - `projscan_analyze` — full project snapshot.
1268
1300
  - `projscan_doctor` — health score + issues with inline `suggestedAction` hints.
1269
1301
  - `projscan_preflight` — compact `proceed` / `caution` / `block` gate with health, changed-file, review, session, plugin, and supply-chain evidence.
@@ -1272,23 +1304,26 @@ The `hotspots` command reads `git log` to build a per-file risk picture. The ris
1272
1304
  - `projscan_structure` — directory tree.
1273
1305
  - `projscan_coverage` — coverage × hotspots, ranked by "risk × uncovered fraction".
1274
1306
 
1275
- *Dependencies (workspace-aware in monorepos):*
1307
+ _Dependencies (workspace-aware in monorepos):_
1308
+
1276
1309
  - `projscan_dependencies` — declared deps + risks, with a `byWorkspace` breakdown.
1277
1310
  - `projscan_outdated` — declared-vs-installed drift (offline), per-package.
1278
1311
  - `projscan_audit` — npm audit, normalized; `package` arg scopes findings to one workspace's direct deps.
1279
1312
  - `projscan_upgrade` — upgrade preview: drift + local CHANGELOG + importers.
1280
1313
 
1281
- *Workspace:*
1314
+ _Workspace:_
1315
+
1282
1316
  - `projscan_workspaces` — list monorepo packages (npm/yarn/pnpm/Nx/Turbo/Lerna).
1283
1317
 
1284
- *Session (1.4+):*
1318
+ _Session (1.4+):_
1319
+
1285
1320
  - `projscan_session` — durable cross-invocation session. Subactions: `current`, `touched`, `events`, `reset`. Auto-populated from every tool result and from `notifications/file_changed` push events when `--watch` is on.
1286
1321
 
1287
1322
  **Every tool accepts `max_tokens` (optional).** projscan estimates serialized output and truncates the largest array field until it fits. Over-budget responses include a `_budget: { truncated: true, estimatedTokens, maxTokens }` field. Tools that return arrays also support cursor pagination via `cursor` + `page_size`.
1288
1323
 
1289
1324
  **Every tool result also carries a `_cost` sidecar (1.5+).** `_cost: { estimatedTokens: N }` lets agents see what they paid for a call without counting tokens themselves — useful for budgeting tool sequences. Cost is the chars-divided-by-4 approximation of the serialized payload (within ~±15% of GPT/Claude tokenizers for code-shaped output).
1290
1325
 
1291
- **`projscan_review` accepts `max_cost_tokens` (1.5+).** Adaptive shape budget. The tool picks a tier based on the value and reshapes the response *before* serializing — different from `max_tokens` (post-hoc truncation):
1326
+ **`projscan_review` accepts `max_cost_tokens` (1.5+).** Adaptive shape budget. The tool picks a tier based on the value and reshapes the response _before_ serializing — different from `max_tokens` (post-hoc truncation):
1292
1327
 
1293
1328
  - **full** (no budget, or ≥ 7000): everything — full structural diff + per-changed-file lists + all cycles + risky functions + dependency changes.
1294
1329
  - **summary** (3000–6999): verdict + summary + top-5 changed files + top-3 of each list, with the heavy per-file expansion arrays stripped.
@@ -1301,14 +1336,16 @@ The chosen tier is surfaced as a top-level `tier` field on the response and lift
1301
1336
  For the analyzer and reporter plugin platform, including minimal manifests, analyzer modules, and `--reporter <name>`, see [Plugin Authoring](PLUGIN-AUTHORING.md). Reporter plugins are the supported boundary for custom presentation, white-label reports, and team-branded CLI summaries; the built-in HTML reporter remains the default core renderer.
1302
1337
 
1303
1338
  **Prompts (6, parameterized with live project data):**
1339
+
1304
1340
  - `prioritize_refactoring` — ranked plan grounded in current hotspots
1305
1341
  - `investigate_file` — senior-engineer brief for a specific file
1306
- - `refactor_hotspot` *(1.5+)* — step-by-step refactor plan for one hotspot file
1307
- - `triage_doctor_issues` *(1.5+)* — critical / important / backlog ordering of open issues
1308
- - `review_this_pr` *(1.5+)* — PR-comment-ready review primed with the structural diff and verdict
1309
- - `safely_rename_symbol` *(1.5+)* — ordered rename + verification checklist via `projscan_impact` blast radius
1342
+ - `refactor_hotspot` _(1.5+)_ — step-by-step refactor plan for one hotspot file
1343
+ - `triage_doctor_issues` _(1.5+)_ — critical / important / backlog ordering of open issues
1344
+ - `review_this_pr` _(1.5+)_ — PR-comment-ready review primed with the structural diff and verdict
1345
+ - `safely_rename_symbol` _(1.5+)_ — ordered rename + verification checklist via `projscan_impact` blast radius
1310
1346
 
1311
1347
  **Resources (3, readable on demand):**
1348
+
1312
1349
  - `projscan://health`
1313
1350
  - `projscan://hotspots`
1314
1351
  - `projscan://structure`
@@ -1332,7 +1369,7 @@ claude mcp add projscan -- npx projscan mcp
1332
1369
  }
1333
1370
  ```
1334
1371
 
1335
- Once connected, your agent can ask *"what are the riskiest files in this repo?"* or *"run projscan_doctor before proposing an edit"* and get grounded answers.
1372
+ Once connected, your agent can ask _"what are the riskiest files in this repo?"_ or _"run projscan_doctor before proposing an edit"_ and get grounded answers.
1336
1373
 
1337
1374
  ---
1338
1375
 
@@ -1340,14 +1377,15 @@ Once connected, your agent can ask *"what are the riskiest files in this repo?"*
1340
1377
 
1341
1378
  ProjScan is designed to be fast enough to run on every save or as a pre-commit hook.
1342
1379
 
1343
- | Metric | Target |
1344
- |--------|--------|
1345
- | 5,000 files | < 1.5 seconds |
1346
- | 20,000 files | < 3 seconds |
1347
- | Network requests | Zero |
1348
- | Runtime dependencies | 4 packages |
1380
+ | Metric | Target |
1381
+ | -------------------- | ------------- |
1382
+ | 5,000 files | < 1.5 seconds |
1383
+ | 20,000 files | < 3 seconds |
1384
+ | Network requests | Zero |
1385
+ | Runtime dependencies | 4 packages |
1349
1386
 
1350
1387
  **How it stays fast:**
1388
+
1351
1389
  - Uses `fast-glob` for file walking
1352
1390
  - Language detection is a pure function - no I/O, just extension mapping
1353
1391
  - Framework detection reads at most one file (`package.json`) plus checks file names already in memory
@@ -1420,14 +1458,14 @@ on:
1420
1458
 
1421
1459
  permissions:
1422
1460
  contents: read
1423
- security-events: write # required for SARIF upload
1461
+ security-events: write # required for SARIF upload
1424
1462
 
1425
1463
  jobs:
1426
1464
  scan:
1427
1465
  runs-on: ubuntu-latest
1428
1466
  steps:
1429
1467
  - uses: actions/checkout@v4
1430
- with: { fetch-depth: 0 } # needed for --changed-only
1468
+ with: { fetch-depth: 0 } # needed for --changed-only
1431
1469
  - uses: actions/setup-node@v4
1432
1470
  with: { node-version: 22 }
1433
1471
  - uses: abhiyoheswaran1/projscan@v1
@@ -1498,6 +1536,7 @@ If scanning takes more than a few seconds, check whether you have large unignore
1498
1536
  ### `--changed-only` reports everything
1499
1537
 
1500
1538
  Check stderr for a warning. Most common causes:
1539
+
1501
1540
  - Running outside a git repository
1502
1541
  - The base ref doesn't exist (e.g., `origin/main` isn't fetched in a shallow CI clone - set `fetch-depth: 0` in checkout)
1503
1542
  - Fresh commit with no parent (no `HEAD~1`)
@@ -1582,6 +1621,7 @@ src/
1582
1621
  ```
1583
1622
 
1584
1623
  **Key design decisions:**
1624
+
1585
1625
  - **Single `types.ts`** - avoids circular dependencies between modules
1586
1626
  - **ESM-only** - required by chalk v5 and ora v8; all imports use `.js` extensions
1587
1627
  - **Pure functions where possible** - `detectLanguages` is pure (no I/O), trivially testable