projscan 4.3.0 → 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 (684) hide show
  1. package/CONTRIBUTING.md +5 -1
  2. package/PRIVACY.md +1 -0
  3. package/README.md +307 -234
  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 +422 -3
  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 +10 -39
  269. package/dist/core/missionProof.js.map +1 -1
  270. package/dist/core/missionProofBaseline.d.ts +10 -0
  271. package/dist/core/missionProofBaseline.js +137 -0
  272. package/dist/core/missionProofBaseline.js.map +1 -0
  273. package/dist/core/missionProofMarkdown.d.ts +2 -0
  274. package/dist/core/missionProofMarkdown.js +83 -0
  275. package/dist/core/missionProofMarkdown.js.map +1 -0
  276. package/dist/core/missionProofSummary.d.ts +2 -0
  277. package/dist/core/missionProofSummary.js +16 -0
  278. package/dist/core/missionProofSummary.js.map +1 -0
  279. package/dist/core/monorepo.d.ts +1 -1
  280. package/dist/core/monorepo.js +4 -2
  281. package/dist/core/monorepo.js.map +1 -1
  282. package/dist/core/onboarding.d.ts +2 -1
  283. package/dist/core/onboarding.js.map +1 -1
  284. package/dist/core/outdatedDetector.js +5 -1
  285. package/dist/core/outdatedDetector.js.map +1 -1
  286. package/dist/core/ownership.js +3 -1
  287. package/dist/core/ownership.js.map +1 -1
  288. package/dist/core/pathClassifiers.js.map +1 -1
  289. package/dist/core/pluginDx.js +2 -1
  290. package/dist/core/pluginDx.js.map +1 -1
  291. package/dist/core/pluginTrust.js +1 -3
  292. package/dist/core/pluginTrust.js.map +1 -1
  293. package/dist/core/plugins.js +5 -5
  294. package/dist/core/plugins.js.map +1 -1
  295. package/dist/core/prDiff.d.ts +1 -2
  296. package/dist/core/prDiff.js +5 -1
  297. package/dist/core/prDiff.js.map +1 -1
  298. package/dist/core/preflight.js +15 -6
  299. package/dist/core/preflight.js.map +1 -1
  300. package/dist/core/privacy.js.map +1 -1
  301. package/dist/core/qualityScorecard.d.ts +1 -1
  302. package/dist/core/qualityScorecard.js +43 -11
  303. package/dist/core/qualityScorecard.js.map +1 -1
  304. package/dist/core/regressionPlan.js +25 -7
  305. package/dist/core/regressionPlan.js.map +1 -1
  306. package/dist/core/releaseEvidence.js +41 -17
  307. package/dist/core/releaseEvidence.js.map +1 -1
  308. package/dist/core/releaseTrain.js +66 -38
  309. package/dist/core/releaseTrain.js.map +1 -1
  310. package/dist/core/repositoryScanner.js +1 -3
  311. package/dist/core/repositoryScanner.js.map +1 -1
  312. package/dist/core/review.d.ts +1 -1
  313. package/dist/core/review.js +72 -10
  314. package/dist/core/review.js.map +1 -1
  315. package/dist/core/reviewDataflow.js +7 -1
  316. package/dist/core/reviewDataflow.js.map +1 -1
  317. package/dist/core/reviewPublicSurface.d.ts +13 -0
  318. package/dist/core/reviewPublicSurface.js +134 -0
  319. package/dist/core/reviewPublicSurface.js.map +1 -0
  320. package/dist/core/roadmapCatalog.js +122 -23
  321. package/dist/core/roadmapCatalog.js.map +1 -1
  322. package/dist/core/searchIndex.js +124 -17
  323. package/dist/core/searchIndex.js.map +1 -1
  324. package/dist/core/semanticGraph.js.map +1 -1
  325. package/dist/core/semanticSearch.js +20 -4
  326. package/dist/core/semanticSearch.js.map +1 -1
  327. package/dist/core/session.js +1 -2
  328. package/dist/core/session.js.map +1 -1
  329. package/dist/core/sessionResources.js +6 -2
  330. package/dist/core/sessionResources.js.map +1 -1
  331. package/dist/core/start.d.ts +3 -9
  332. package/dist/core/start.js +22 -3231
  333. package/dist/core/start.js.map +1 -1
  334. package/dist/core/startAdoptionLoop.d.ts +2 -0
  335. package/dist/core/startAdoptionLoop.js +41 -0
  336. package/dist/core/startAdoptionLoop.js.map +1 -0
  337. package/dist/core/startEvidence.d.ts +5 -0
  338. package/dist/core/startEvidence.js +62 -0
  339. package/dist/core/startEvidence.js.map +1 -0
  340. package/dist/core/startExecutionPlan.d.ts +16 -0
  341. package/dist/core/startExecutionPlan.js +185 -0
  342. package/dist/core/startExecutionPlan.js.map +1 -0
  343. package/dist/core/startHarness.d.ts +3 -0
  344. package/dist/core/startHarness.js +47 -0
  345. package/dist/core/startHarness.js.map +1 -0
  346. package/dist/core/startIntentTargets.d.ts +24 -0
  347. package/dist/core/startIntentTargets.js +1106 -0
  348. package/dist/core/startIntentTargets.js.map +1 -0
  349. package/dist/core/startMissionControl.d.ts +16 -0
  350. package/dist/core/startMissionControl.js +145 -0
  351. package/dist/core/startMissionControl.js.map +1 -0
  352. package/dist/core/startMissionPolicy.d.ts +19 -0
  353. package/dist/core/startMissionPolicy.js +246 -0
  354. package/dist/core/startMissionPolicy.js.map +1 -0
  355. package/dist/core/startMode.d.ts +11 -0
  356. package/dist/core/startMode.js +139 -0
  357. package/dist/core/startMode.js.map +1 -0
  358. package/dist/core/startOptions.d.ts +18 -0
  359. package/dist/core/startOptions.js +29 -0
  360. package/dist/core/startOptions.js.map +1 -0
  361. package/dist/core/startResume.d.ts +7 -0
  362. package/dist/core/startResume.js +468 -0
  363. package/dist/core/startResume.js.map +1 -0
  364. package/dist/core/startReviewGate.d.ts +11 -0
  365. package/dist/core/startReviewGate.js +200 -0
  366. package/dist/core/startReviewGate.js.map +1 -0
  367. package/dist/core/startRouteActions.d.ts +7 -0
  368. package/dist/core/startRouteActions.js +497 -0
  369. package/dist/core/startRouteActions.js.map +1 -0
  370. package/dist/core/startRunbook.d.ts +24 -0
  371. package/dist/core/startRunbook.js +271 -0
  372. package/dist/core/startRunbook.js.map +1 -0
  373. package/dist/core/startSuccessCriteria.d.ts +14 -0
  374. package/dist/core/startSuccessCriteria.js +497 -0
  375. package/dist/core/startSuccessCriteria.js.map +1 -0
  376. package/dist/core/taint.js +12 -3
  377. package/dist/core/taint.js.map +1 -1
  378. package/dist/core/telemetry.js +19 -5
  379. package/dist/core/telemetry.js.map +1 -1
  380. package/dist/core/trial.d.ts +1 -1
  381. package/dist/core/trial.js +15 -6
  382. package/dist/core/trial.js.map +1 -1
  383. package/dist/core/understand.d.ts +1 -1
  384. package/dist/core/understand.js +165 -51
  385. package/dist/core/understand.js.map +1 -1
  386. package/dist/core/upgradePreview.js +1 -1
  387. package/dist/core/upgradePreview.js.map +1 -1
  388. package/dist/core/watcher.js +18 -3
  389. package/dist/core/watcher.js.map +1 -1
  390. package/dist/core/workplan.js +87 -17
  391. package/dist/core/workplan.js.map +1 -1
  392. package/dist/core/workspace.js.map +1 -1
  393. package/dist/index.d.ts +12 -9
  394. package/dist/index.js +10 -7
  395. package/dist/index.js.map +1 -1
  396. package/dist/mcp/pagination.js.map +1 -1
  397. package/dist/mcp/prompts.js +28 -20
  398. package/dist/mcp/prompts.js.map +1 -1
  399. package/dist/mcp/server.js +6 -74
  400. package/dist/mcp/server.js.map +1 -1
  401. package/dist/mcp/serverPayload.d.ts +13 -0
  402. package/dist/mcp/serverPayload.js +61 -0
  403. package/dist/mcp/serverPayload.js.map +1 -0
  404. package/dist/mcp/tokenBudget.js.map +1 -1
  405. package/dist/mcp/tools/_shared.js.map +1 -1
  406. package/dist/mcp/tools/agentBrief.js +7 -1
  407. package/dist/mcp/tools/agentBrief.js.map +1 -1
  408. package/dist/mcp/tools/applyFix.js +1 -1
  409. package/dist/mcp/tools/applyFix.js.map +1 -1
  410. package/dist/mcp/tools/audit.js.map +1 -1
  411. package/dist/mcp/tools/bugHunt.js +2 -2
  412. package/dist/mcp/tools/bugHunt.js.map +1 -1
  413. package/dist/mcp/tools/claim.js +8 -3
  414. package/dist/mcp/tools/claim.js.map +1 -1
  415. package/dist/mcp/tools/collision.js +3 -1
  416. package/dist/mcp/tools/collision.js.map +1 -1
  417. package/dist/mcp/tools/coordinate.js.map +1 -1
  418. package/dist/mcp/tools/coordinateWatch.js +5 -2
  419. package/dist/mcp/tools/coordinateWatch.js.map +1 -1
  420. package/dist/mcp/tools/costSummary.js.map +1 -1
  421. package/dist/mcp/tools/coupling.js.map +1 -1
  422. package/dist/mcp/tools/coverage.js.map +1 -1
  423. package/dist/mcp/tools/dataflow.js.map +1 -1
  424. package/dist/mcp/tools/dependencies.js +4 -1
  425. package/dist/mcp/tools/dependencies.js.map +1 -1
  426. package/dist/mcp/tools/doctor.js.map +1 -1
  427. package/dist/mcp/tools/explainIssue.js +4 -1
  428. package/dist/mcp/tools/explainIssue.js.map +1 -1
  429. package/dist/mcp/tools/fixSuggest.js +5 -2
  430. package/dist/mcp/tools/fixSuggest.js.map +1 -1
  431. package/dist/mcp/tools/hotspots.js +4 -1
  432. package/dist/mcp/tools/hotspots.js.map +1 -1
  433. package/dist/mcp/tools/impact.js +10 -3
  434. package/dist/mcp/tools/impact.js.map +1 -1
  435. package/dist/mcp/tools/mergeRisk.js.map +1 -1
  436. package/dist/mcp/tools/plugin.js +6 -1
  437. package/dist/mcp/tools/plugin.js.map +1 -1
  438. package/dist/mcp/tools/prDiff.js.map +1 -1
  439. package/dist/mcp/tools/preflight.js +1 -5
  440. package/dist/mcp/tools/preflight.js.map +1 -1
  441. package/dist/mcp/tools/review.js.map +1 -1
  442. package/dist/mcp/tools/reviewWatch.d.ts +1 -1
  443. package/dist/mcp/tools/reviewWatch.js +9 -9
  444. package/dist/mcp/tools/reviewWatch.js.map +1 -1
  445. package/dist/mcp/tools/route.js +1 -1
  446. package/dist/mcp/tools/route.js.map +1 -1
  447. package/dist/mcp/tools/search.js.map +1 -1
  448. package/dist/mcp/tools/semanticGraph.js +8 -2
  449. package/dist/mcp/tools/semanticGraph.js.map +1 -1
  450. package/dist/mcp/tools/start.js.map +1 -1
  451. package/dist/mcp/tools/structure.js +7 -1
  452. package/dist/mcp/tools/structure.js.map +1 -1
  453. package/dist/mcp/tools/understand.js.map +1 -1
  454. package/dist/mcp/tools/workspaceGraph.js +10 -1
  455. package/dist/mcp/tools/workspaceGraph.js.map +1 -1
  456. package/dist/mcp/tools.js +3 -1
  457. package/dist/mcp/tools.js.map +1 -1
  458. package/dist/projscan-sbom.cdx.json +2136 -904
  459. package/dist/reporters/consoleAnalysisReporter.d.ts +2 -0
  460. package/dist/reporters/consoleAnalysisReporter.js +89 -0
  461. package/dist/reporters/consoleAnalysisReporter.js.map +1 -0
  462. package/dist/reporters/consoleArchitectureReporter.d.ts +3 -0
  463. package/dist/reporters/consoleArchitectureReporter.js +47 -0
  464. package/dist/reporters/consoleArchitectureReporter.js.map +1 -0
  465. package/dist/reporters/consoleAuditReporter.d.ts +2 -0
  466. package/dist/reporters/consoleAuditReporter.js +46 -0
  467. package/dist/reporters/consoleAuditReporter.js.map +1 -0
  468. package/dist/reporters/consoleCiReporter.d.ts +2 -0
  469. package/dist/reporters/consoleCiReporter.js +27 -0
  470. package/dist/reporters/consoleCiReporter.js.map +1 -0
  471. package/dist/reporters/consoleCouplingReporter.d.ts +2 -0
  472. package/dist/reporters/consoleCouplingReporter.js +53 -0
  473. package/dist/reporters/consoleCouplingReporter.js.map +1 -0
  474. package/dist/reporters/consoleCoverageReporter.d.ts +2 -0
  475. package/dist/reporters/consoleCoverageReporter.js +62 -0
  476. package/dist/reporters/consoleCoverageReporter.js.map +1 -0
  477. package/dist/reporters/consoleDependencyReporter.d.ts +2 -0
  478. package/dist/reporters/consoleDependencyReporter.js +64 -0
  479. package/dist/reporters/consoleDependencyReporter.js.map +1 -0
  480. package/dist/reporters/consoleDiffReporter.d.ts +2 -0
  481. package/dist/reporters/consoleDiffReporter.js +80 -0
  482. package/dist/reporters/consoleDiffReporter.js.map +1 -0
  483. package/dist/reporters/consoleExplanationReporter.d.ts +2 -0
  484. package/dist/reporters/consoleExplanationReporter.js +33 -0
  485. package/dist/reporters/consoleExplanationReporter.js.map +1 -0
  486. package/dist/reporters/consoleFileReporter.d.ts +2 -0
  487. package/dist/reporters/consoleFileReporter.js +133 -0
  488. package/dist/reporters/consoleFileReporter.js.map +1 -0
  489. package/dist/reporters/consoleFixGuidanceReporter.d.ts +8 -0
  490. package/dist/reporters/consoleFixGuidanceReporter.js +135 -0
  491. package/dist/reporters/consoleFixGuidanceReporter.js.map +1 -0
  492. package/dist/reporters/consoleHealthReporter.d.ts +13 -0
  493. package/dist/reporters/consoleHealthReporter.js +111 -0
  494. package/dist/reporters/consoleHealthReporter.js.map +1 -0
  495. package/dist/reporters/consoleHotspotReporter.d.ts +2 -0
  496. package/dist/reporters/consoleHotspotReporter.js +68 -0
  497. package/dist/reporters/consoleHotspotReporter.js.map +1 -0
  498. package/dist/reporters/consoleImpactReporter.d.ts +2 -0
  499. package/dist/reporters/consoleImpactReporter.js +65 -0
  500. package/dist/reporters/consoleImpactReporter.js.map +1 -0
  501. package/dist/reporters/consoleOutdatedReporter.d.ts +2 -0
  502. package/dist/reporters/consoleOutdatedReporter.js +54 -0
  503. package/dist/reporters/consoleOutdatedReporter.js.map +1 -0
  504. package/dist/reporters/consolePrDiffReporter.d.ts +2 -0
  505. package/dist/reporters/consolePrDiffReporter.js +75 -0
  506. package/dist/reporters/consolePrDiffReporter.js.map +1 -0
  507. package/dist/reporters/consoleReporter.d.ts +21 -38
  508. package/dist/reporters/consoleReporter.js +19 -1000
  509. package/dist/reporters/consoleReporter.js.map +1 -1
  510. package/dist/reporters/consoleReviewReporter.d.ts +2 -0
  511. package/dist/reporters/consoleReviewReporter.js +101 -0
  512. package/dist/reporters/consoleReviewReporter.js.map +1 -0
  513. package/dist/reporters/consoleUpgradeReporter.d.ts +2 -0
  514. package/dist/reporters/consoleUpgradeReporter.js +67 -0
  515. package/dist/reporters/consoleUpgradeReporter.js.map +1 -0
  516. package/dist/reporters/consoleWorkspaceReporter.d.ts +2 -0
  517. package/dist/reporters/consoleWorkspaceReporter.js +24 -0
  518. package/dist/reporters/consoleWorkspaceReporter.js.map +1 -0
  519. package/dist/reporters/htmlReporter.d.ts +2 -1
  520. package/dist/reporters/htmlReporter.js +9 -3
  521. package/dist/reporters/htmlReporter.js.map +1 -1
  522. package/dist/reporters/jsonReporter.d.ts +2 -1
  523. package/dist/reporters/jsonReporter.js.map +1 -1
  524. package/dist/reporters/markdownAnalysisReporter.d.ts +2 -0
  525. package/dist/reporters/markdownAnalysisReporter.js +40 -0
  526. package/dist/reporters/markdownAnalysisReporter.js.map +1 -0
  527. package/dist/reporters/markdownAuditReporter.d.ts +2 -0
  528. package/dist/reporters/markdownAuditReporter.js +27 -0
  529. package/dist/reporters/markdownAuditReporter.js.map +1 -0
  530. package/dist/reporters/markdownDependencyReporter.d.ts +2 -0
  531. package/dist/reporters/markdownDependencyReporter.js +33 -0
  532. package/dist/reporters/markdownDependencyReporter.js.map +1 -0
  533. package/dist/reporters/markdownDiffReporter.d.ts +2 -0
  534. package/dist/reporters/markdownDiffReporter.js +65 -0
  535. package/dist/reporters/markdownDiffReporter.js.map +1 -0
  536. package/dist/reporters/markdownFileReporter.d.ts +2 -0
  537. package/dist/reporters/markdownFileReporter.js +92 -0
  538. package/dist/reporters/markdownFileReporter.js.map +1 -0
  539. package/dist/reporters/markdownFixGuidanceReporter.d.ts +8 -0
  540. package/dist/reporters/markdownFixGuidanceReporter.js +95 -0
  541. package/dist/reporters/markdownFixGuidanceReporter.js.map +1 -0
  542. package/dist/reporters/markdownImpactReporter.d.ts +2 -0
  543. package/dist/reporters/markdownImpactReporter.js +52 -0
  544. package/dist/reporters/markdownImpactReporter.js.map +1 -0
  545. package/dist/reporters/markdownReporter.d.ts +10 -16
  546. package/dist/reporters/markdownReporter.js +9 -452
  547. package/dist/reporters/markdownReporter.js.map +1 -1
  548. package/dist/reporters/markdownReviewReporter.d.ts +2 -0
  549. package/dist/reporters/markdownReviewReporter.js +84 -0
  550. package/dist/reporters/markdownReviewReporter.js.map +1 -0
  551. package/dist/reporters/markdownUpgradeReporter.d.ts +2 -0
  552. package/dist/reporters/markdownUpgradeReporter.js +47 -0
  553. package/dist/reporters/markdownUpgradeReporter.js.map +1 -0
  554. package/dist/reporters/sarifReporter.js.map +1 -1
  555. package/dist/tool-manifest.json +4 -4
  556. package/dist/types/agentBrief.d.ts +48 -0
  557. package/dist/types/agentBrief.js +2 -0
  558. package/dist/types/agentBrief.js.map +1 -0
  559. package/dist/types/analysis.d.ts +32 -0
  560. package/dist/types/analysis.js +2 -0
  561. package/dist/types/analysis.js.map +1 -0
  562. package/dist/types/baseline.d.ts +59 -0
  563. package/dist/types/baseline.js +2 -0
  564. package/dist/types/baseline.js.map +1 -0
  565. package/dist/types/bugHunt.d.ts +41 -0
  566. package/dist/types/bugHunt.js +2 -0
  567. package/dist/types/bugHunt.js.map +1 -0
  568. package/dist/types/common.d.ts +34 -0
  569. package/dist/types/common.js +2 -0
  570. package/dist/types/common.js.map +1 -0
  571. package/dist/types/config.d.ts +56 -0
  572. package/dist/types/config.js +2 -0
  573. package/dist/types/config.js.map +1 -0
  574. package/dist/types/coupling.d.ts +40 -0
  575. package/dist/types/coupling.js +2 -0
  576. package/dist/types/coupling.js.map +1 -0
  577. package/dist/types/coverage.d.ts +32 -0
  578. package/dist/types/coverage.js +2 -0
  579. package/dist/types/coverage.js.map +1 -0
  580. package/dist/types/dependencyHealth.d.ts +61 -0
  581. package/dist/types/dependencyHealth.js +2 -0
  582. package/dist/types/dependencyHealth.js.map +1 -0
  583. package/dist/types/dogfood.d.ts +185 -0
  584. package/dist/types/dogfood.js +2 -0
  585. package/dist/types/dogfood.js.map +1 -0
  586. package/dist/types/evidencePack.d.ts +76 -0
  587. package/dist/types/evidencePack.js +2 -0
  588. package/dist/types/evidencePack.js.map +1 -0
  589. package/dist/types/fixes.d.ts +77 -0
  590. package/dist/types/fixes.js +2 -0
  591. package/dist/types/fixes.js.map +1 -0
  592. package/dist/types/graph.d.ts +80 -0
  593. package/dist/types/graph.js +2 -0
  594. package/dist/types/graph.js.map +1 -0
  595. package/dist/types/graphCorpus.d.ts +16 -0
  596. package/dist/types/graphCorpus.js +2 -0
  597. package/dist/types/graphCorpus.js.map +1 -0
  598. package/dist/types/hotspots.d.ts +42 -0
  599. package/dist/types/hotspots.js +2 -0
  600. package/dist/types/hotspots.js.map +1 -0
  601. package/dist/types/impact.d.ts +62 -0
  602. package/dist/types/impact.js +2 -0
  603. package/dist/types/impact.js.map +1 -0
  604. package/dist/types/inspection.d.ts +47 -0
  605. package/dist/types/inspection.js +2 -0
  606. package/dist/types/inspection.js.map +1 -0
  607. package/dist/types/mcp.d.ts +39 -0
  608. package/dist/types/mcp.js +2 -0
  609. package/dist/types/mcp.js.map +1 -0
  610. package/dist/types/pluginDx.d.ts +42 -0
  611. package/dist/types/pluginDx.js +2 -0
  612. package/dist/types/pluginDx.js.map +1 -0
  613. package/dist/types/prDiff.d.ts +41 -0
  614. package/dist/types/prDiff.js +2 -0
  615. package/dist/types/prDiff.js.map +1 -0
  616. package/dist/types/preflight.d.ts +122 -0
  617. package/dist/types/preflight.js +2 -0
  618. package/dist/types/preflight.js.map +1 -0
  619. package/dist/types/qualityScorecard.d.ts +34 -0
  620. package/dist/types/qualityScorecard.js +2 -0
  621. package/dist/types/qualityScorecard.js.map +1 -0
  622. package/dist/types/regressionPlan.d.ts +32 -0
  623. package/dist/types/regressionPlan.js +2 -0
  624. package/dist/types/regressionPlan.js.map +1 -0
  625. package/dist/types/releaseTrain.d.ts +37 -0
  626. package/dist/types/releaseTrain.js +2 -0
  627. package/dist/types/releaseTrain.js.map +1 -0
  628. package/dist/types/review.d.ts +203 -0
  629. package/dist/types/review.js +2 -0
  630. package/dist/types/review.js.map +1 -0
  631. package/dist/types/reviewContract.d.ts +9 -0
  632. package/dist/types/reviewContract.js +2 -0
  633. package/dist/types/reviewContract.js.map +1 -0
  634. package/dist/types/scanning.d.ts +111 -0
  635. package/dist/types/scanning.js +2 -0
  636. package/dist/types/scanning.js.map +1 -0
  637. package/dist/types/session.d.ts +42 -0
  638. package/dist/types/session.js +2 -0
  639. package/dist/types/session.js.map +1 -0
  640. package/dist/types/start.d.ts +437 -0
  641. package/dist/types/start.js +2 -0
  642. package/dist/types/start.js.map +1 -0
  643. package/dist/types/trial.d.ts +27 -0
  644. package/dist/types/trial.js +2 -0
  645. package/dist/types/trial.js.map +1 -0
  646. package/dist/types/understand.d.ts +153 -0
  647. package/dist/types/understand.js +2 -0
  648. package/dist/types/understand.js.map +1 -0
  649. package/dist/types/workplan.d.ts +67 -0
  650. package/dist/types/workplan.js +2 -0
  651. package/dist/types/workplan.js.map +1 -0
  652. package/dist/types/workplanHandoff.d.ts +11 -0
  653. package/dist/types/workplanHandoff.js +2 -0
  654. package/dist/types/workplanHandoff.js.map +1 -0
  655. package/dist/types/workspace.d.ts +18 -0
  656. package/dist/types/workspace.js +2 -0
  657. package/dist/types/workspace.js.map +1 -0
  658. package/dist/types.d.ts +34 -2348
  659. package/dist/types.js +0 -1
  660. package/dist/types.js.map +1 -1
  661. package/dist/utils/banner.js +15 -6
  662. package/dist/utils/banner.js.map +1 -1
  663. package/dist/utils/baseline.js +11 -9
  664. package/dist/utils/baseline.js.map +1 -1
  665. package/dist/utils/changedFiles.js +1 -1
  666. package/dist/utils/changedFiles.js.map +1 -1
  667. package/dist/utils/config.d.ts +2 -1
  668. package/dist/utils/config.js.map +1 -1
  669. package/dist/utils/formatSupport.d.ts +2 -2
  670. package/dist/utils/formatSupport.js +8 -2
  671. package/dist/utils/formatSupport.js.map +1 -1
  672. package/dist/utils/packageJsonLocator.js.map +1 -1
  673. package/docs/GUIDE.md +209 -147
  674. package/docs/PLUGIN-GALLERY.md +9 -1
  675. package/docs/ROADMAP.md +69 -68
  676. package/docs/demos/projscan-4-1-demo.html +46 -79
  677. package/docs/demos/projscan-mission-control.tape +13 -0
  678. package/docs/demos/projscan-mission-proof.tape +25 -0
  679. package/docs/examples/plugins/graph-context.mjs +1 -2
  680. package/docs/examples/plugins/security-sensitive-files.mjs +2 -1
  681. package/docs/projscan-mission-control.gif +0 -0
  682. package/docs/projscan-mission-proof.gif +0 -0
  683. package/package.json +17 -5
  684. package/scripts/capture-vhs-demos.mjs +80 -0
package/docs/GUIDE.md CHANGED
@@ -81,6 +81,7 @@ npx projscan
81
81
  - Node.js >= 18
82
82
  - npm, yarn, or pnpm
83
83
  - Git (optional - unlocks `hotspots` and `--changed-only`)
84
+ - VHS (optional - regenerates checked-in terminal demos with `npm run docs:demos`)
84
85
 
85
86
  ---
86
87
 
@@ -111,7 +112,7 @@ projscan is structured around the four questions an AI coding agent (or a carefu
111
112
 
112
113
  ### 1. Diagnose — "what's wrong here?"
113
114
 
114
- 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?_
115
116
 
116
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.
117
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.
@@ -179,7 +180,9 @@ When the agent first opens a repo, or before starting a refactor, the question i
179
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`.
180
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.
181
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.
182
- 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.
183
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`.
184
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.
185
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`.
@@ -189,7 +192,7 @@ When the agent first opens a repo, or before starting a refactor, the question i
189
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`.
190
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.
191
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`.
192
- - **`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.
193
196
  - **`projscan_agent_brief` / `projscan agent-brief`** — compact next-agent context packet with focus items, repo context, coordination hints, guardrails, and suggested next actions.
194
197
  - **`projscan_quality_scorecard` / `projscan quality-scorecard`** — dimensioned quality view across health, security, tests, maintainability, coordination, top risks, and verification commands.
195
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.
@@ -205,16 +208,37 @@ When the agent first opens a repo, or before starting a refactor, the question i
205
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.
206
209
  - **`projscan_analyze` / `projscan analyze`** — the everything report; useful at session start but verbose.
207
210
 
208
- **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.
209
212
 
210
- 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.
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.
214
+
215
+ #### Mission Control demos
216
+
217
+ The checked-in VHS demos show the current terminal flow without manual screen recording.
218
+
219
+ <img src="projscan-mission-control.gif" alt="projscan Mission Control shortcut menu for a plain-language goal" width="760">
220
+
221
+ ```bash
222
+ npx projscan start --save-mission .projscan/mission --intent "what breaks if I rename the auth token loader?"
223
+ cd .projscan/mission && ./mission.sh && ./status.sh && ./review.sh
224
+ npx projscan start --mission .projscan/mission
225
+ npx projscan mission-proof --mission .projscan/mission --format markdown
226
+ ```
227
+
228
+ <img src="projscan-mission-proof.gif" alt="projscan Mission Proof report and resume command reading a saved Mission Control bundle" width="760">
229
+
230
+ Regenerate the demos with:
231
+
232
+ ```bash
233
+ npm run docs:demos
234
+ ```
211
235
 
212
236
  ### 2. Review — "is this PR safe to merge?"
213
237
 
214
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?"
215
239
 
216
- - **`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.
217
- - **`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.
218
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.
219
243
 
220
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.
@@ -223,18 +247,18 @@ When the agent has changes in flight (or is asked to review someone else's), the
223
247
 
224
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.
225
249
 
226
- - **`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.
227
- - **`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.
228
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.
229
253
 
230
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.
231
255
 
232
256
  ### 4. Reach — "what breaks if I change this?"
233
257
 
234
- 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?_
235
259
 
236
- - **`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.
237
- - **`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.)_
238
262
 
239
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.
240
264
 
@@ -242,12 +266,12 @@ Before the agent commits to a refactor (or accepts a name-rename suggestion), th
242
266
 
243
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.
244
268
 
245
- - **`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.
246
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.
247
- - **`--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`.
248
- - **`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.
249
- - **`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`.
250
- - **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.
251
275
 
252
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.
253
277
 
@@ -264,6 +288,7 @@ projscan analyze
264
288
  The flagship command. Runs every detection module and produces the full project report.
265
289
 
266
290
  **What it does internally:**
291
+
267
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.
268
293
  2. Builds a language breakdown by mapping file extensions to language names
269
294
  3. Detects frameworks by inspecting `package.json` dependencies and config file presence
@@ -274,9 +299,9 @@ The flagship command. Runs every detection module and produces the full project
274
299
 
275
300
  **Options:**
276
301
 
277
- | Flag | Description |
278
- |------|-------------|
279
- | `--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 |
280
305
  | `--base-ref <ref>` | Git base ref for `--changed-only` (default: origin/main) |
281
306
 
282
307
  <img src="https://abhiyoheswaran.com/images/projscan/hero-poster.png" alt="npx projscan analyze: banner, scan progress, full project report" width="700">
@@ -293,14 +318,15 @@ Use this when you want a quick "is this project in good shape?" answer without t
293
318
 
294
319
  **Options:**
295
320
 
296
- | Flag | Description |
297
- |------|-------------|
298
- | `--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 |
299
324
  | `--base-ref <ref>` | Git base ref for `--changed-only` (default: origin/main) |
300
325
 
301
326
  <img src="npx%20projscan%20doctor.gif" alt="npx projscan doctor" width="700">
302
327
 
303
328
  **Severity levels:**
329
+
304
330
  - **error** (✖) - Problems that should be addressed immediately
305
331
  - **warning** (⚠) - Issues that affect code quality or maintainability
306
332
  - **info** (ℹ) - Suggestions for best practices
@@ -317,12 +343,13 @@ Ranks files by **risk** - a combination of git churn, complexity (lines of code)
317
343
 
318
344
  **Options:**
319
345
 
320
- | Flag | Description | Default |
321
- |------|-------------|---------|
322
- | `--limit <n>` | Number of hotspots to show | 10 (or `hotspots.limit` from `.projscanrc`) |
323
- | `--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` |
324
350
 
325
351
  **What you get per file:**
352
+
326
353
  - `riskScore` - combined score (0–100)
327
354
  - `churn` - number of commits touching the file in the window
328
355
  - `distinctAuthors` - how many people have touched it
@@ -357,14 +384,14 @@ import a package.
357
384
 
358
385
  **Options:**
359
386
 
360
- | Flag | Description | Default |
361
- |------|-------------|---------|
362
- | `--max-nodes <n>` | Maximum nodes to return | 10000 |
363
- | `--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 |
364
391
  | `--query <direction>` | Targeted query: `imports`, `exports`, `importers`, `symbol_defs`, or `package_importers` | full graph |
365
- | `--file <path>` | Repo-relative file for `imports`, `exports`, or `importers` | - |
366
- | `--symbol <name>` | Symbol/package for `symbol_defs` or `package_importers` | - |
367
- | `--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 |
368
395
 
369
396
  ### understand
370
397
 
@@ -380,21 +407,21 @@ Repo understanding for engineers before they edit. The command returns a cited r
380
407
 
381
408
  Views:
382
409
 
383
- | View | Use it for |
384
- |------|------------|
385
- | `map` | Orient around entrypoints, package boundaries, read-first files, risks, and unknowns |
386
- | `flow` | Trace runtime paths and side-effect sinks through graph-backed evidence |
387
- | `contracts` | Inspect public exports, config/env contracts, and likely breaking-change risks |
388
- | `change` | Tie an intent to blast radius, first safe edit, owner state, rollback, and verification commands |
389
- | `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 |
390
417
 
391
418
  **Options:**
392
419
 
393
- | Flag | Description | Default |
394
- |------|-------------|---------|
395
- | `--view <view>` | `map`, `flow`, `contracts`, `change`, or `verify` | `map` |
396
- | `--intent <text>` | Planned change or question for change-readiness output | none |
397
- | `--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 |
398
425
 
399
426
  ### dataflow
400
427
 
@@ -412,13 +439,13 @@ For release hardening, `npm run check:graph-corpus` compares bundled fixture met
412
439
 
413
440
  **Options:**
414
441
 
415
- | Flag | Description | Default |
416
- |------|-------------|---------|
417
- | `--source <name...>` | Add custom source identifiers | Built-ins + config |
418
- | `--sink <name...>` | Add custom sink identifiers | Built-ins + config |
419
- | `--max-risks <n>` | Maximum risks to return | 50 |
420
- | `--include-tests` | Include risks that touch test files | false |
421
- | `--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 |
422
449
 
423
450
  ### search
424
451
 
@@ -435,14 +462,15 @@ BM25-ranked search across content, symbol names, and path tokens. No embeddings,
435
462
 
436
463
  **Scopes:**
437
464
 
438
- | Scope | What it matches | Ranking |
439
- |-------|-----------------|---------|
440
- | `auto` (default) | Content, with symbol + path boost | BM25 + symbol boost × 2.0 + path boost × 0.5 |
441
- | `content` | Same as `auto` | BM25 |
442
- | `symbols` | Names of exported functions/classes/types/etc. | Exact → prefix → substring |
443
- | `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 |
444
471
 
445
472
  **Query handling:**
473
+
446
474
  - Tokens are split on camelCase, snake_case, and digits. `userAuthToken` indexes as `user`, `auth`, `token`.
447
475
  - Light stemming (trailing `-s`, `-ing`, `-ed` stripped).
448
476
  - Stopwords and TypeScript keywords filtered (`the`, `function`, `class`, `export`, …).
@@ -451,7 +479,8 @@ BM25-ranked search across content, symbol names, and path tokens. No embeddings,
451
479
  **Output includes:** file path, line number, a one-line excerpt centered on the first matching line, the match score, and which tokens matched.
452
480
 
453
481
  **Limitations:**
454
- - 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).
455
484
  - Index is rebuilt on every run (fast - the AST is already parsed from the code-graph cache).
456
485
 
457
486
  ### file
@@ -468,7 +497,7 @@ Per-file drill-down. Combines everything ProjScan knows about a file into one vi
468
497
  - **Related issues** - every open issue whose `locations` reference the file
469
498
  - **Inline smells** - large files, `console.log`, TODO/FIXME, `any` types
470
499
 
471
- 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.
472
501
 
473
502
  ### ci
474
503
 
@@ -480,11 +509,11 @@ A CI-pipeline-friendly health gate. Runs the full health check and exits with co
480
509
 
481
510
  **Options:**
482
511
 
483
- | Flag | Description | Default |
484
- |------|-------------|---------|
485
- | `--min-score <n>` | Minimum passing score (0–100) | `minScore` from `.projscanrc`, else 70 |
486
- | `--changed-only` | Gate only on issues in files changed vs base ref | off |
487
- | `--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) |
488
517
 
489
518
  **Example:**
490
519
 
@@ -497,6 +526,7 @@ projscan: B (82/100) - 0 errors, 2 warnings, 1 info - PASS (threshold: 80)
497
526
  <img src="npx%20projscan%20ci%20--min-score%2070.gif" alt="npx projscan ci" width="700">
498
527
 
499
528
  **Exit codes:**
529
+
500
530
  - `0` - Score meets or exceeds the threshold
501
531
  - `1` - Score is below the threshold
502
532
 
@@ -531,9 +561,9 @@ Compare your project's current health and hotspots against a saved baseline. Use
531
561
 
532
562
  **Options:**
533
563
 
534
- | Flag | Description |
535
- |------|-------------|
536
- | `--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 |
537
567
  | `--baseline <path>` | Path to baseline file (default: `.projscan-baseline.json`) |
538
568
 
539
569
  **Workflow:**
@@ -571,12 +601,12 @@ projscan fix -y
571
601
 
572
602
  **Available fixes:**
573
603
 
574
- | Fix | What it creates | What it installs |
575
- |-----|----------------|-----------------|
576
- | ESLint | `eslint.config.js` (with TypeScript support if TS is detected) | `eslint`, `@eslint/js`, optionally `typescript-eslint` |
577
- | Prettier | `.prettierrc` with sensible defaults | `prettier` |
578
- | Test framework | `vitest.config.ts` + sample test file, adds `test` script to package.json | `vitest` |
579
- | 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 |
580
610
 
581
611
  ### diagram
582
612
 
@@ -617,6 +647,7 @@ projscan outdated
617
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.
618
648
 
619
649
  **Output fields per package:**
650
+
620
651
  - `declared` - the range in `package.json` (e.g., `^1.2.3`)
621
652
  - `installed` - the concrete version in `node_modules`, or `null` if not installed
622
653
  - `latest` - same as `installed` in this offline drift check
@@ -647,9 +678,9 @@ Each finding becomes a SARIF result with `ruleId: audit-<pkg>`, severity mapped
647
678
 
648
679
  **Options:**
649
680
 
650
- | Flag | Description | Default |
651
- |------|-------------|---------|
652
- | `--timeout <ms>` | Override npm audit timeout | 60000 |
681
+ | Flag | Description | Default |
682
+ | ---------------- | -------------------------- | ------- |
683
+ | `--timeout <ms>` | Override npm audit timeout | 60000 |
653
684
 
654
685
  ### upgrade
655
686
 
@@ -660,6 +691,7 @@ projscan upgrade <package>
660
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.
661
692
 
662
693
  **What you get:**
694
+
663
695
  - Drift classification (`patch` / `minor` / `major`)
664
696
  - Breaking-change markers found in the CHANGELOG: scans for `BREAKING CHANGE`, `deprecated`, `removed support`, `no longer supported`, and section headers containing "breaking"
665
697
  - CHANGELOG excerpt sliced to the relevant version range (read from `node_modules/<pkg>/CHANGELOG.md`)
@@ -682,6 +714,7 @@ $ projscan upgrade react --format markdown
682
714
  ```
683
715
 
684
716
  **Limitations:**
717
+
685
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."
686
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`.
687
720
 
@@ -694,11 +727,13 @@ projscan coverage
694
727
  Joins test coverage with the hotspot ranking and produces a list sorted by "risk × uncovered fraction" - the files that most deserve tests.
695
728
 
696
729
  **Supported formats** (auto-detected in this order):
730
+
697
731
  - `coverage/lcov.info` - lcov format (Vitest, Jest, c8)
698
732
  - `coverage/coverage-final.json` - Istanbul per-file detail
699
733
  - `coverage/coverage-summary.json` - Istanbul summary
700
734
 
701
735
  **Output fields per entry:**
736
+
702
737
  - `relativePath` - file path
703
738
  - `riskScore` - the file's hotspot risk
704
739
  - `coverage` - line coverage %, or `null` if the file isn't in the coverage report
@@ -707,8 +742,8 @@ Joins test coverage with the hotspot ranking and produces a list sorted by "risk
707
742
 
708
743
  **Options:**
709
744
 
710
- | Flag | Description | Default |
711
- |------|-------------|---------|
745
+ | Flag | Description | Default |
746
+ | ------------- | --------------------------- | ------------ |
712
747
  | `--limit <n>` | Number of entries to return | 30 (max 200) |
713
748
 
714
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.
@@ -736,7 +771,7 @@ With `--watch`, the server starts an in-process file watcher and emits a JSON-RP
736
771
 
737
772
  See [MCP Server for AI Agents](#mcp-server-for-ai-agents).
738
773
 
739
- ### session *(1.4+)*
774
+ ### session _(1.4+)_
740
775
 
741
776
  ```bash
742
777
  projscan session # current session summary
@@ -807,22 +842,23 @@ Every `projscan doctor` and `projscan badge` run calculates a health score from
807
842
  **Scoring:**
808
843
 
809
844
  | Severity | Deduction per issue |
810
- |----------|-------------------|
811
- | Error | -20 points |
812
- | Warning | -10 points |
813
- | Info | -3 points |
845
+ | -------- | ------------------- |
846
+ | Error | -20 points |
847
+ | Warning | -10 points |
848
+ | Info | -3 points |
814
849
 
815
850
  **Grade thresholds:**
816
851
 
817
- | Grade | Score Range | Meaning |
818
- |-------|-------------|---------|
819
- | A | 90–100 | Excellent - project follows best practices |
820
- | B | 80–89 | Good - minor improvements possible |
821
- | C | 70–79 | Fair - several issues to address |
822
- | D | 60–69 | Poor - significant issues found |
823
- | 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 |
824
859
 
825
860
  The score appears in all output formats:
861
+
826
862
  - **Console**: Shown at the top of the doctor report
827
863
  - **JSON**: Included as `health.score` and `health.grade` fields
828
864
  - **Markdown**: Shown as a heading with an auto-generated shields.io badge
@@ -876,6 +912,7 @@ projscan ci --format sarif > projscan.sarif
876
912
  ```
877
913
 
878
914
  Supported on `analyze`, `audit`, `ci`, `doctor`, and `outdated`. Each issue is emitted as a SARIF `result` with:
915
+
879
916
  - `ruleId` - stable rule identifier (e.g., `hardcoded-secret`, `missing-prettier`)
880
917
  - `level` - `error`, `warning`, or `note` (mapped from projscan severity)
881
918
  - `message.text` - the issue description
@@ -923,18 +960,18 @@ ProjScan loads a project-wide config from one of:
923
960
 
924
961
  ### Fields
925
962
 
926
- | Field | Type | Effect |
927
- |-------|------|--------|
928
- | `minScore` | number (0–100) | Default threshold for `projscan ci`. Clamped to 0–100. |
929
- | `baseRef` | string | Default base ref for `--changed-only`. |
930
- | `ignore` | string[] | Extra glob patterns added to the built-in ignore list (`node_modules`, `.git`, `dist`, `build`, `coverage`, `.next`, `.nuxt`, `.cache`, `.turbo`, `.output`). |
931
- | `scan.includeIgnored` | boolean | Explicitly include files hidden by Git ignore rules. Default `false`. |
932
- | `scan.scanEnvValues` | boolean | Explicitly read `.env*` contents during secret-pattern checks. Default `false`; `.env` files are path-only. |
933
- | `scan.offline` | boolean | Block projscan network-capable features: telemetry sending, `audit`, registry checks, and optional semantic model loading. Default `false`. |
934
- | `disableRules` | string[] | Silence rules by id. Exact match (`missing-prettier`) or wildcard prefix (`large-*`). |
935
- | `severityOverrides` | `Record<string, 'info' \| 'warning' \| 'error'>` | Remap a rule's severity. Useful for downgrading project-specific false positives without disabling them. |
936
- | `hotspots.limit` | number (1–100) | Default limit for `projscan hotspots`. |
937
- | `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`. |
938
975
 
939
976
  Invalid JSON in a discovered config file is a hard error - projscan exits rather than silently ignoring it.
940
977
 
@@ -952,7 +989,7 @@ If you prefer to keep everything in `package.json`:
952
989
  }
953
990
  ```
954
991
 
955
- ### Monorepo: cross-package import policy *(0.14+)*
992
+ ### Monorepo: cross-package import policy _(0.14+)_
956
993
 
957
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.
958
995
 
@@ -1013,19 +1050,19 @@ Example GitHub Actions snippet:
1013
1050
 
1014
1051
  ## Global Options
1015
1052
 
1016
- | Option | Description |
1017
- |--------|-------------|
1018
- | `--format <type>` | Output format: `console` (default), `json`, `markdown`, `sarif`, `html` (command-dependent) |
1019
- | `--config <path>` | Path to a `.projscanrc` config file |
1020
- | `--include-ignored` | Explicitly include files hidden by Git ignore rules |
1021
- | `--scan-env-values` | Explicitly read `.env*` contents during secret checks |
1022
- | `--offline` | Block projscan network-capable features for this run |
1023
- | `--changed-only` | Scope to files changed vs base ref (applies to `analyze`, `doctor`, `ci`) |
1024
- | `--base-ref <ref>` | Git base ref for `--changed-only` (default: origin/main) |
1025
- | `--verbose` | Show debug-level logging - useful for diagnosing scan issues |
1026
- | `--quiet` | Suppress all non-essential output (spinners, status messages) |
1027
- | `-V, --version` | Print the version number |
1028
- | `-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 |
1029
1066
 
1030
1067
  **Per-command help:**
1031
1068
 
@@ -1063,31 +1100,37 @@ Each detection has a **confidence level** (high, medium, low) and a **category**
1063
1100
  ProjScan ships with six analyzer modules:
1064
1101
 
1065
1102
  #### 1. ESLint Check
1103
+
1066
1104
  - Looks for `.eslintrc.*`, `eslint.config.*`, or `eslintConfig` in package.json
1067
1105
  - If missing: warning with auto-fix available
1068
1106
 
1069
1107
  #### 2. Prettier Check
1108
+
1070
1109
  - Looks for `.prettierrc`, `.prettierrc.*`, `prettier.config.*`, or `prettier` in package.json
1071
1110
  - If missing: warning with auto-fix available
1072
1111
 
1073
1112
  #### 3. Test Check
1113
+
1074
1114
  - Looks for test frameworks in devDependencies (vitest, jest, mocha, etc.)
1075
1115
  - Looks for test files (`*.test.*`, `*.spec.*`, `__tests__/`)
1076
1116
  - If no framework: warning with auto-fix available
1077
1117
  - If framework exists but zero test files: separate warning
1078
1118
 
1079
1119
  #### 4. Architecture Check
1120
+
1080
1121
  - **Large utility directories**: warns if `utils/`, `helpers/`, or `lib/` contains 10+ files (issue anchored to the directory path)
1081
1122
  - **Missing .editorconfig**: info with auto-fix available
1082
1123
  - **Missing/empty README**: warning / info
1083
1124
 
1084
1125
  #### 5. Dependency Risk Check
1126
+
1085
1127
  - Warns if production dependencies exceed 50
1086
1128
  - Errors if total dependencies exceed 100
1087
1129
  - Flags `*` or `latest` version ranges
1088
1130
  - Warns if no lock file is present
1089
1131
 
1090
1132
  #### 6. Security Check
1133
+
1091
1134
  - **Committed `.env` files**: Flags `.env`, `.env.local`, `.env.production`, etc. (but not `.env.example`, `.env.sample`, `.env.template`) - location anchored to the file
1092
1135
  - **Private key files**: Detects `.pem`, `.key`, `id_rsa`, `id_ed25519`, `.p12`, `.pfx` files
1093
1136
  - **Hardcoded secrets**: Scans file contents (files under 512KB) for:
@@ -1096,7 +1139,7 @@ ProjScan ships with six analyzer modules:
1096
1139
  - Slack tokens (`xoxb-...`, `xoxp-...`)
1097
1140
  - Generic patterns (`password=`, `secret=`, `api_key=` with quoted values)
1098
1141
  - PEM private key headers
1099
- 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.
1100
1143
  - **Missing `.gitignore` entries**: Warns if `.env` is not in `.gitignore`
1101
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
1102
1145
 
@@ -1120,11 +1163,13 @@ The fix system is intentionally conservative. It only creates configuration file
1120
1163
  ### Fix details
1121
1164
 
1122
1165
  **ESLint fix:**
1166
+
1123
1167
  - Creates `eslint.config.js` using the flat config format (ESLint v9+)
1124
1168
  - If TypeScript files are detected, includes `typescript-eslint` plugin
1125
1169
  - Installs `eslint` and `@eslint/js` via the detected package manager
1126
1170
 
1127
1171
  **Prettier fix:**
1172
+
1128
1173
  - Creates `.prettierrc` with these defaults:
1129
1174
  ```json
1130
1175
  {
@@ -1138,12 +1183,14 @@ The fix system is intentionally conservative. It only creates configuration file
1138
1183
  - Installs `prettier`
1139
1184
 
1140
1185
  **Test framework fix:**
1186
+
1141
1187
  - Creates `vitest.config.ts`
1142
1188
  - Creates a sample test file at `tests/example.test.ts`
1143
1189
  - Adds `"test": "vitest run"` to package.json scripts (if not already present)
1144
1190
  - Installs `vitest`
1145
1191
 
1146
1192
  **EditorConfig fix:**
1193
+
1147
1194
  - Creates `.editorconfig`
1148
1195
  - Installs nothing - EditorConfig is handled by editor plugins
1149
1196
 
@@ -1167,6 +1214,7 @@ This is heuristic-based and works best with conventional project structures. Pro
1167
1214
  The `explain` command performs regex-based static analysis. It does not execute your code or make network calls.
1168
1215
 
1169
1216
  **Import detection** handles:
1217
+
1170
1218
  - ES modules: `import { foo } from 'bar'`
1171
1219
  - Default imports: `import foo from 'bar'`
1172
1220
  - Namespace imports: `import * as foo from 'bar'`
@@ -1174,11 +1222,13 @@ The `explain` command performs regex-based static analysis. It does not execute
1174
1222
  - CommonJS: `const foo = require('bar')`
1175
1223
 
1176
1224
  **Export detection** handles:
1225
+
1177
1226
  - Named exports: `export function`, `export class`, `export const`
1178
1227
  - Type exports: `export interface`, `export type`
1179
1228
  - Default exports: `export default`
1180
1229
 
1181
1230
  **Purpose inference** is based on file name and directory conventions. For example:
1231
+
1182
1232
  - Files named `*.test.*` or `*.spec.*` → "Test file"
1183
1233
  - Files in `routes/` → "Route definitions"
1184
1234
  - Files named `index.ts` → "Module entry point"
@@ -1190,15 +1240,16 @@ The `explain` command performs regex-based static analysis. It does not execute
1190
1240
 
1191
1241
  The `hotspots` command reads `git log` to build a per-file risk picture. The risk score combines five signals:
1192
1242
 
1193
- | Signal | Weight | Intuition |
1194
- |--------|--------|-----------|
1195
- | Churn | 0.40 | Files that change often are more likely to harbor bugs |
1196
- | 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.** |
1197
- | Issue density | 0.20 | Files that already have open issues need help |
1198
- | Recency | 0.10 | Recently touched hot files deserve attention first |
1199
- | 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 |
1200
1250
 
1201
1251
  **Ownership signals:**
1252
+
1202
1253
  - `primaryAuthor` - the top committer by share
1203
1254
  - `primaryAuthorShare` - fraction of commits (0–1)
1204
1255
  - `topAuthors` - ranked list
@@ -1207,6 +1258,7 @@ The `hotspots` command reads `git log` to build a per-file risk picture. The ris
1207
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.
1208
1259
 
1209
1260
  **What "hotspots" can't do:**
1261
+
1210
1262
  - It's a heuristic, not a proof. Low-risk files may still have bugs.
1211
1263
  - It weights LOC as a proxy for complexity; a clean 1,000-line file may rank higher than it deserves.
1212
1264
  - It has no visibility into logical coupling - two small files that change together still look independent.
@@ -1221,16 +1273,17 @@ The `hotspots` command reads `git log` to build a per-file risk picture. The ris
1221
1273
 
1222
1274
  **Core tools include:**
1223
1275
 
1224
- *Structural / agent-native:*
1276
+ _Structural / agent-native:_
1277
+
1225
1278
  - `projscan_start` — first-60-seconds repo orientation with setup diagnostics, recommended workflow, top risks, adoption gaps, and next commands.
1226
- - `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.)_
1227
1280
  - `projscan_dataflow` — direct, propagated, and bridge source-to-sink dataflow risks over the function graph.
1228
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.
1229
1282
  - `projscan_coupling` — per-file fan-in / fan-out / instability + Tarjan circular-import cycles.
1230
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.
1231
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`).
1232
1285
  - `projscan_workplan` — prioritized agent execution plan with evidence, suggested tools, verification commands, coordination context, and handoff text.
1233
- - `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.
1234
1287
  - `projscan_agent_brief` — compact next-agent context packet with focus items, guardrails, repo context, and suggested next actions.
1235
1288
  - `projscan_quality_scorecard` — dimensioned quality view with top risks and verification commands.
1236
1289
  - `projscan_adoption` — adoption helper for MCP client snippets, MCP setup doctor, agent workflow recipes, and first-run diagnostics.
@@ -1241,7 +1294,8 @@ The `hotspots` command reads `git log` to build a per-file risk picture. The ris
1241
1294
  - `projscan_explain_issue` — deep dive on one issue: code excerpt, related issues, similar past commits via `git log --grep`, plus the structured FixSuggestion.
1242
1295
  - `projscan_impact` — transitive blast-radius for a file or symbol. BFS over reverse imports + symbol callsites. Cycle-safe; depth-bounded.
1243
1296
 
1244
- *Analysis:*
1297
+ _Analysis:_
1298
+
1245
1299
  - `projscan_analyze` — full project snapshot.
1246
1300
  - `projscan_doctor` — health score + issues with inline `suggestedAction` hints.
1247
1301
  - `projscan_preflight` — compact `proceed` / `caution` / `block` gate with health, changed-file, review, session, plugin, and supply-chain evidence.
@@ -1250,23 +1304,26 @@ The `hotspots` command reads `git log` to build a per-file risk picture. The ris
1250
1304
  - `projscan_structure` — directory tree.
1251
1305
  - `projscan_coverage` — coverage × hotspots, ranked by "risk × uncovered fraction".
1252
1306
 
1253
- *Dependencies (workspace-aware in monorepos):*
1307
+ _Dependencies (workspace-aware in monorepos):_
1308
+
1254
1309
  - `projscan_dependencies` — declared deps + risks, with a `byWorkspace` breakdown.
1255
1310
  - `projscan_outdated` — declared-vs-installed drift (offline), per-package.
1256
1311
  - `projscan_audit` — npm audit, normalized; `package` arg scopes findings to one workspace's direct deps.
1257
1312
  - `projscan_upgrade` — upgrade preview: drift + local CHANGELOG + importers.
1258
1313
 
1259
- *Workspace:*
1314
+ _Workspace:_
1315
+
1260
1316
  - `projscan_workspaces` — list monorepo packages (npm/yarn/pnpm/Nx/Turbo/Lerna).
1261
1317
 
1262
- *Session (1.4+):*
1318
+ _Session (1.4+):_
1319
+
1263
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.
1264
1321
 
1265
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`.
1266
1323
 
1267
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).
1268
1325
 
1269
- **`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):
1270
1327
 
1271
1328
  - **full** (no budget, or ≥ 7000): everything — full structural diff + per-changed-file lists + all cycles + risky functions + dependency changes.
1272
1329
  - **summary** (3000–6999): verdict + summary + top-5 changed files + top-3 of each list, with the heavy per-file expansion arrays stripped.
@@ -1279,14 +1336,16 @@ The chosen tier is surfaced as a top-level `tier` field on the response and lift
1279
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.
1280
1337
 
1281
1338
  **Prompts (6, parameterized with live project data):**
1339
+
1282
1340
  - `prioritize_refactoring` — ranked plan grounded in current hotspots
1283
1341
  - `investigate_file` — senior-engineer brief for a specific file
1284
- - `refactor_hotspot` *(1.5+)* — step-by-step refactor plan for one hotspot file
1285
- - `triage_doctor_issues` *(1.5+)* — critical / important / backlog ordering of open issues
1286
- - `review_this_pr` *(1.5+)* — PR-comment-ready review primed with the structural diff and verdict
1287
- - `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
1288
1346
 
1289
1347
  **Resources (3, readable on demand):**
1348
+
1290
1349
  - `projscan://health`
1291
1350
  - `projscan://hotspots`
1292
1351
  - `projscan://structure`
@@ -1310,7 +1369,7 @@ claude mcp add projscan -- npx projscan mcp
1310
1369
  }
1311
1370
  ```
1312
1371
 
1313
- 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.
1314
1373
 
1315
1374
  ---
1316
1375
 
@@ -1318,14 +1377,15 @@ Once connected, your agent can ask *"what are the riskiest files in this repo?"*
1318
1377
 
1319
1378
  ProjScan is designed to be fast enough to run on every save or as a pre-commit hook.
1320
1379
 
1321
- | Metric | Target |
1322
- |--------|--------|
1323
- | 5,000 files | < 1.5 seconds |
1324
- | 20,000 files | < 3 seconds |
1325
- | Network requests | Zero |
1326
- | 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 |
1327
1386
 
1328
1387
  **How it stays fast:**
1388
+
1329
1389
  - Uses `fast-glob` for file walking
1330
1390
  - Language detection is a pure function - no I/O, just extension mapping
1331
1391
  - Framework detection reads at most one file (`package.json`) plus checks file names already in memory
@@ -1398,14 +1458,14 @@ on:
1398
1458
 
1399
1459
  permissions:
1400
1460
  contents: read
1401
- security-events: write # required for SARIF upload
1461
+ security-events: write # required for SARIF upload
1402
1462
 
1403
1463
  jobs:
1404
1464
  scan:
1405
1465
  runs-on: ubuntu-latest
1406
1466
  steps:
1407
1467
  - uses: actions/checkout@v4
1408
- with: { fetch-depth: 0 } # needed for --changed-only
1468
+ with: { fetch-depth: 0 } # needed for --changed-only
1409
1469
  - uses: actions/setup-node@v4
1410
1470
  with: { node-version: 22 }
1411
1471
  - uses: abhiyoheswaran1/projscan@v1
@@ -1476,6 +1536,7 @@ If scanning takes more than a few seconds, check whether you have large unignore
1476
1536
  ### `--changed-only` reports everything
1477
1537
 
1478
1538
  Check stderr for a warning. Most common causes:
1539
+
1479
1540
  - Running outside a git repository
1480
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)
1481
1542
  - Fresh commit with no parent (no `HEAD~1`)
@@ -1560,6 +1621,7 @@ src/
1560
1621
  ```
1561
1622
 
1562
1623
  **Key design decisions:**
1624
+
1563
1625
  - **Single `types.ts`** - avoids circular dependencies between modules
1564
1626
  - **ESM-only** - required by chalk v5 and ora v8; all imports use `.js` extensions
1565
1627
  - **Pure functions where possible** - `detectLanguages` is pure (no I/O), trivially testable