webmcp-cli 1.0.0 → 1.2.1

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 (347) hide show
  1. package/dist/agent/features/agent-simulator.d.ts +67 -0
  2. package/dist/agent/features/agent-simulator.js +368 -0
  3. package/dist/agent/features/agent-simulator.js.map +1 -0
  4. package/dist/agent/features/index.d.ts +8 -0
  5. package/dist/agent/features/index.js +9 -0
  6. package/dist/agent/features/index.js.map +1 -0
  7. package/dist/agent/features/simulation-judge.d.ts +78 -0
  8. package/dist/agent/features/simulation-judge.js +276 -0
  9. package/dist/agent/features/simulation-judge.js.map +1 -0
  10. package/dist/agent/features/test-case-generator.d.ts +35 -0
  11. package/dist/agent/features/test-case-generator.js +257 -0
  12. package/dist/agent/features/test-case-generator.js.map +1 -0
  13. package/dist/agent/index.d.ts +7 -0
  14. package/dist/agent/index.js +10 -0
  15. package/dist/agent/index.js.map +1 -0
  16. package/dist/agent/llm-client.d.ts +76 -0
  17. package/dist/agent/llm-client.js +198 -0
  18. package/dist/agent/llm-client.js.map +1 -0
  19. package/dist/audit/run-single-page-audit.d.ts +41 -0
  20. package/dist/audit/run-single-page-audit.js +103 -0
  21. package/dist/audit/run-single-page-audit.js.map +1 -0
  22. package/dist/bin/webmcp.d.ts +5 -0
  23. package/dist/bin/webmcp.js +14 -0
  24. package/dist/bin/webmcp.js.map +1 -0
  25. package/dist/browser/audit-runner.d.ts +30 -0
  26. package/dist/browser/audit-runner.js +77 -0
  27. package/dist/browser/audit-runner.js.map +1 -0
  28. package/dist/browser/index.d.ts +6 -0
  29. package/dist/browser/index.js +7 -0
  30. package/dist/browser/index.js.map +1 -0
  31. package/dist/browser/interceptor.d.ts +68 -0
  32. package/dist/browser/interceptor.js +257 -0
  33. package/dist/browser/interceptor.js.map +1 -0
  34. package/dist/browser/playwright.d.ts +98 -0
  35. package/dist/browser/playwright.js +158 -0
  36. package/dist/browser/playwright.js.map +1 -0
  37. package/dist/cli/commands/audit.d.ts +12 -0
  38. package/dist/cli/commands/audit.js +349 -0
  39. package/dist/cli/commands/audit.js.map +1 -0
  40. package/dist/cli/commands/interactive.d.ts +10 -0
  41. package/dist/cli/commands/interactive.js +34 -0
  42. package/dist/cli/commands/interactive.js.map +1 -0
  43. package/dist/cli/index.d.ts +17 -0
  44. package/dist/cli/index.js +84 -0
  45. package/dist/cli/index.js.map +1 -0
  46. package/dist/cli/options/parse-audit-options.d.ts +12 -0
  47. package/dist/cli/options/parse-audit-options.js +64 -0
  48. package/dist/cli/options/parse-audit-options.js.map +1 -0
  49. package/dist/core/constants.d.ts +102 -0
  50. package/dist/core/constants.js +214 -0
  51. package/dist/core/constants.js.map +1 -0
  52. package/dist/core/types/audit.d.ts +260 -0
  53. package/dist/core/types/audit.js +5 -0
  54. package/dist/core/types/audit.js.map +1 -0
  55. package/dist/core/types/index.d.ts +6 -0
  56. package/dist/core/types/index.js +7 -0
  57. package/dist/core/types/index.js.map +1 -0
  58. package/dist/core/types/rule.d.ts +190 -0
  59. package/dist/core/types/rule.js +26 -0
  60. package/dist/core/types/rule.js.map +1 -0
  61. package/dist/core/types/tool.d.ts +312 -0
  62. package/dist/core/types/tool.js +6 -0
  63. package/dist/core/types/tool.js.map +1 -0
  64. package/dist/detection/declarative.d.ts +27 -0
  65. package/dist/detection/declarative.js +343 -0
  66. package/dist/detection/declarative.js.map +1 -0
  67. package/dist/detection/imperative.d.ts +38 -0
  68. package/dist/detection/imperative.js +99 -0
  69. package/dist/detection/imperative.js.map +1 -0
  70. package/dist/detection/index.d.ts +5 -0
  71. package/dist/detection/index.js +6 -0
  72. package/dist/detection/index.js.map +1 -0
  73. package/dist/index.d.ts +12 -0
  74. package/dist/index.js +19 -0
  75. package/dist/index.js.map +1 -0
  76. package/dist/llm/advice-service.d.ts +38 -0
  77. package/dist/llm/advice-service.js +243 -0
  78. package/dist/llm/advice-service.js.map +1 -0
  79. package/dist/llm/evaluator.d.ts +89 -0
  80. package/dist/llm/evaluator.js +274 -0
  81. package/dist/llm/evaluator.js.map +1 -0
  82. package/dist/llm/index.d.ts +11 -0
  83. package/dist/llm/index.js +15 -0
  84. package/dist/llm/index.js.map +1 -0
  85. package/dist/llm/json-response.d.ts +12 -0
  86. package/dist/llm/json-response.js +67 -0
  87. package/dist/llm/json-response.js.map +1 -0
  88. package/dist/llm/providers/mock.d.ts +29 -0
  89. package/dist/llm/providers/mock.js +324 -0
  90. package/dist/llm/providers/mock.js.map +1 -0
  91. package/dist/llm/providers/openrouter.d.ts +53 -0
  92. package/dist/llm/providers/openrouter.js +321 -0
  93. package/dist/llm/providers/openrouter.js.map +1 -0
  94. package/dist/llm/request-cache.d.ts +28 -0
  95. package/dist/llm/request-cache.js +99 -0
  96. package/dist/llm/request-cache.js.map +1 -0
  97. package/dist/llm/types.d.ts +233 -0
  98. package/dist/llm/types.js +7 -0
  99. package/dist/llm/types.js.map +1 -0
  100. package/dist/rules/best-practices/BP-001.d.ts +11 -0
  101. package/dist/rules/best-practices/BP-001.js +56 -0
  102. package/dist/rules/best-practices/BP-001.js.map +1 -0
  103. package/dist/rules/best-practices/BP-002.d.ts +11 -0
  104. package/dist/rules/best-practices/BP-002.js +63 -0
  105. package/dist/rules/best-practices/BP-002.js.map +1 -0
  106. package/dist/rules/best-practices/BP-003.d.ts +11 -0
  107. package/dist/rules/best-practices/BP-003.js +68 -0
  108. package/dist/rules/best-practices/BP-003.js.map +1 -0
  109. package/dist/rules/coverage/COV-001.d.ts +8 -0
  110. package/dist/rules/coverage/COV-001.js +51 -0
  111. package/dist/rules/coverage/COV-001.js.map +1 -0
  112. package/dist/rules/description/DESC-003.d.ts +13 -0
  113. package/dist/rules/description/DESC-003.js +96 -0
  114. package/dist/rules/description/DESC-003.js.map +1 -0
  115. package/dist/rules/description/DESC-004.d.ts +8 -0
  116. package/dist/rules/description/DESC-004.js +61 -0
  117. package/dist/rules/description/DESC-004.js.map +1 -0
  118. package/dist/rules/description/DESC-005.d.ts +12 -0
  119. package/dist/rules/description/DESC-005.js +70 -0
  120. package/dist/rules/description/DESC-005.js.map +1 -0
  121. package/dist/rules/description/index.d.ts +4 -0
  122. package/dist/rules/description/index.js +5 -0
  123. package/dist/rules/description/index.js.map +1 -0
  124. package/dist/rules/implementation/IMP-001.d.ts +10 -0
  125. package/dist/rules/implementation/IMP-001.js +36 -0
  126. package/dist/rules/implementation/IMP-001.js.map +1 -0
  127. package/dist/rules/implementation/IMP-003.d.ts +9 -0
  128. package/dist/rules/implementation/IMP-003.js +45 -0
  129. package/dist/rules/implementation/IMP-003.js.map +1 -0
  130. package/dist/rules/implementation/IMP-004.d.ts +9 -0
  131. package/dist/rules/implementation/IMP-004.js +48 -0
  132. package/dist/rules/implementation/IMP-004.js.map +1 -0
  133. package/dist/rules/implementation/IMP-005.d.ts +9 -0
  134. package/dist/rules/implementation/IMP-005.js +54 -0
  135. package/dist/rules/implementation/IMP-005.js.map +1 -0
  136. package/dist/rules/implementation/IMP-007.d.ts +8 -0
  137. package/dist/rules/implementation/IMP-007.js +79 -0
  138. package/dist/rules/implementation/IMP-007.js.map +1 -0
  139. package/dist/rules/implementation/IMP-013.d.ts +9 -0
  140. package/dist/rules/implementation/IMP-013.js +55 -0
  141. package/dist/rules/implementation/IMP-013.js.map +1 -0
  142. package/dist/rules/implementation/index.d.ts +9 -0
  143. package/dist/rules/implementation/index.js +10 -0
  144. package/dist/rules/implementation/index.js.map +1 -0
  145. package/dist/rules/index.d.ts +51 -0
  146. package/dist/rules/index.js +100 -0
  147. package/dist/rules/index.js.map +1 -0
  148. package/dist/rules/llm/LLM-001.d.ts +14 -0
  149. package/dist/rules/llm/LLM-001.js +78 -0
  150. package/dist/rules/llm/LLM-001.js.map +1 -0
  151. package/dist/rules/llm/LLM-002.d.ts +14 -0
  152. package/dist/rules/llm/LLM-002.js +77 -0
  153. package/dist/rules/llm/LLM-002.js.map +1 -0
  154. package/dist/rules/llm/LLM-003.d.ts +16 -0
  155. package/dist/rules/llm/LLM-003.js +82 -0
  156. package/dist/rules/llm/LLM-003.js.map +1 -0
  157. package/dist/rules/llm/LLM-004.d.ts +14 -0
  158. package/dist/rules/llm/LLM-004.js +87 -0
  159. package/dist/rules/llm/LLM-004.js.map +1 -0
  160. package/dist/rules/llm/LLM-005.d.ts +16 -0
  161. package/dist/rules/llm/LLM-005.js +105 -0
  162. package/dist/rules/llm/LLM-005.js.map +1 -0
  163. package/dist/rules/llm/index.d.ts +10 -0
  164. package/dist/rules/llm/index.js +11 -0
  165. package/dist/rules/llm/index.js.map +1 -0
  166. package/dist/rules/runner.d.ts +54 -0
  167. package/dist/rules/runner.js +138 -0
  168. package/dist/rules/runner.js.map +1 -0
  169. package/dist/rules/schema/SCHEMA-001.d.ts +9 -0
  170. package/dist/rules/schema/SCHEMA-001.js +57 -0
  171. package/dist/rules/schema/SCHEMA-001.js.map +1 -0
  172. package/dist/rules/schema/SCHEMA-002.d.ts +9 -0
  173. package/dist/rules/schema/SCHEMA-002.js +59 -0
  174. package/dist/rules/schema/SCHEMA-002.js.map +1 -0
  175. package/dist/rules/schema/SCHEMA-003.d.ts +10 -0
  176. package/dist/rules/schema/SCHEMA-003.js +66 -0
  177. package/dist/rules/schema/SCHEMA-003.js.map +1 -0
  178. package/dist/rules/schema/SCHEMA-011.d.ts +10 -0
  179. package/dist/rules/schema/SCHEMA-011.js +62 -0
  180. package/dist/rules/schema/SCHEMA-011.js.map +1 -0
  181. package/dist/rules/security/SEC-001.d.ts +12 -0
  182. package/dist/rules/security/SEC-001.js +66 -0
  183. package/dist/rules/security/SEC-001.js.map +1 -0
  184. package/dist/rules/utils/keywords.d.ts +35 -0
  185. package/dist/rules/utils/keywords.js +100 -0
  186. package/dist/rules/utils/keywords.js.map +1 -0
  187. package/dist/scoring/calculator.d.ts +27 -0
  188. package/dist/scoring/calculator.js +194 -0
  189. package/dist/scoring/calculator.js.map +1 -0
  190. package/dist/scoring/grades.d.ts +34 -0
  191. package/dist/scoring/grades.js +167 -0
  192. package/dist/scoring/grades.js.map +1 -0
  193. package/dist/scoring/index.d.ts +5 -0
  194. package/dist/scoring/index.js +6 -0
  195. package/dist/scoring/index.js.map +1 -0
  196. package/dist/ui/banner.d.ts +21 -0
  197. package/dist/ui/banner.js +60 -0
  198. package/dist/ui/banner.js.map +1 -0
  199. package/dist/ui/design-tokens.d.ts +23 -0
  200. package/dist/ui/design-tokens.js +58 -0
  201. package/dist/ui/design-tokens.js.map +1 -0
  202. package/dist/ui/findings.d.ts +23 -0
  203. package/dist/ui/findings.js +190 -0
  204. package/dist/ui/findings.js.map +1 -0
  205. package/dist/ui/index.d.ts +9 -0
  206. package/dist/ui/index.js +10 -0
  207. package/dist/ui/index.js.map +1 -0
  208. package/dist/ui/ink/App.d.ts +14 -0
  209. package/dist/ui/ink/App.js +113 -0
  210. package/dist/ui/ink/App.js.map +1 -0
  211. package/dist/ui/ink/FullScreenLayout.d.ts +16 -0
  212. package/dist/ui/ink/FullScreenLayout.js +29 -0
  213. package/dist/ui/ink/FullScreenLayout.js.map +1 -0
  214. package/dist/ui/ink/InteractiveApp.d.ts +28 -0
  215. package/dist/ui/ink/InteractiveApp.js +229 -0
  216. package/dist/ui/ink/InteractiveApp.js.map +1 -0
  217. package/dist/ui/ink/RealAuditApp.d.ts +19 -0
  218. package/dist/ui/ink/RealAuditApp.js +170 -0
  219. package/dist/ui/ink/RealAuditApp.js.map +1 -0
  220. package/dist/ui/ink/components/AnimatedProgressBar.d.ts +20 -0
  221. package/dist/ui/ink/components/AnimatedProgressBar.js +46 -0
  222. package/dist/ui/ink/components/AnimatedProgressBar.js.map +1 -0
  223. package/dist/ui/ink/components/AsciiLogo.d.ts +12 -0
  224. package/dist/ui/ink/components/AsciiLogo.js +35 -0
  225. package/dist/ui/ink/components/AsciiLogo.js.map +1 -0
  226. package/dist/ui/ink/components/CategoryBars.d.ts +18 -0
  227. package/dist/ui/ink/components/CategoryBars.js +18 -0
  228. package/dist/ui/ink/components/CategoryBars.js.map +1 -0
  229. package/dist/ui/ink/components/FindingsTable.d.ts +18 -0
  230. package/dist/ui/ink/components/FindingsTable.js +19 -0
  231. package/dist/ui/ink/components/FindingsTable.js.map +1 -0
  232. package/dist/ui/ink/components/Footer.d.ts +15 -0
  233. package/dist/ui/ink/components/Footer.js +20 -0
  234. package/dist/ui/ink/components/Footer.js.map +1 -0
  235. package/dist/ui/ink/components/Header.d.ts +11 -0
  236. package/dist/ui/ink/components/Header.js +12 -0
  237. package/dist/ui/ink/components/Header.js.map +1 -0
  238. package/dist/ui/ink/components/LinkList.d.ts +17 -0
  239. package/dist/ui/ink/components/LinkList.js +44 -0
  240. package/dist/ui/ink/components/LinkList.js.map +1 -0
  241. package/dist/ui/ink/components/Navigation.d.ts +26 -0
  242. package/dist/ui/ink/components/Navigation.js +62 -0
  243. package/dist/ui/ink/components/Navigation.js.map +1 -0
  244. package/dist/ui/ink/components/ProgressBar.d.ts +15 -0
  245. package/dist/ui/ink/components/ProgressBar.js +14 -0
  246. package/dist/ui/ink/components/ProgressBar.js.map +1 -0
  247. package/dist/ui/ink/components/ScoreCard.d.ts +30 -0
  248. package/dist/ui/ink/components/ScoreCard.js +26 -0
  249. package/dist/ui/ink/components/ScoreCard.js.map +1 -0
  250. package/dist/ui/ink/components/SimulationResults.d.ts +33 -0
  251. package/dist/ui/ink/components/SimulationResults.js +23 -0
  252. package/dist/ui/ink/components/SimulationResults.js.map +1 -0
  253. package/dist/ui/ink/components/Spinner.d.ts +11 -0
  254. package/dist/ui/ink/components/Spinner.js +12 -0
  255. package/dist/ui/ink/components/Spinner.js.map +1 -0
  256. package/dist/ui/ink/components/ToolCard.d.ts +23 -0
  257. package/dist/ui/ink/components/ToolCard.js +20 -0
  258. package/dist/ui/ink/components/ToolCard.js.map +1 -0
  259. package/dist/ui/ink/components/shared/Badge.d.ts +21 -0
  260. package/dist/ui/ink/components/shared/Badge.js +39 -0
  261. package/dist/ui/ink/components/shared/Badge.js.map +1 -0
  262. package/dist/ui/ink/components/shared/Card.d.ts +18 -0
  263. package/dist/ui/ink/components/shared/Card.js +11 -0
  264. package/dist/ui/ink/components/shared/Card.js.map +1 -0
  265. package/dist/ui/ink/components/shared/HelpOverlay.d.ts +10 -0
  266. package/dist/ui/ink/components/shared/HelpOverlay.js +28 -0
  267. package/dist/ui/ink/components/shared/HelpOverlay.js.map +1 -0
  268. package/dist/ui/ink/components/shared/LoadingWithTimeout.d.ts +11 -0
  269. package/dist/ui/ink/components/shared/LoadingWithTimeout.js +21 -0
  270. package/dist/ui/ink/components/shared/LoadingWithTimeout.js.map +1 -0
  271. package/dist/ui/ink/components/shared/Menu.d.ts +23 -0
  272. package/dist/ui/ink/components/shared/Menu.js +43 -0
  273. package/dist/ui/ink/components/shared/Menu.js.map +1 -0
  274. package/dist/ui/ink/components/shared/Table.d.ts +23 -0
  275. package/dist/ui/ink/components/shared/Table.js +40 -0
  276. package/dist/ui/ink/components/shared/Table.js.map +1 -0
  277. package/dist/ui/ink/components/views/CrawlingView.d.ts +12 -0
  278. package/dist/ui/ink/components/views/CrawlingView.js +34 -0
  279. package/dist/ui/ink/components/views/CrawlingView.js.map +1 -0
  280. package/dist/ui/ink/components/views/DashboardView.d.ts +21 -0
  281. package/dist/ui/ink/components/views/DashboardView.js +51 -0
  282. package/dist/ui/ink/components/views/DashboardView.js.map +1 -0
  283. package/dist/ui/ink/components/views/FindingDetailView.d.ts +16 -0
  284. package/dist/ui/ink/components/views/FindingDetailView.js +34 -0
  285. package/dist/ui/ink/components/views/FindingDetailView.js.map +1 -0
  286. package/dist/ui/ink/components/views/FindingsView.d.ts +16 -0
  287. package/dist/ui/ink/components/views/FindingsView.js +79 -0
  288. package/dist/ui/ink/components/views/FindingsView.js.map +1 -0
  289. package/dist/ui/ink/components/views/OnboardingView.d.ts +12 -0
  290. package/dist/ui/ink/components/views/OnboardingView.js +40 -0
  291. package/dist/ui/ink/components/views/OnboardingView.js.map +1 -0
  292. package/dist/ui/ink/components/views/SimulationView.d.ts +17 -0
  293. package/dist/ui/ink/components/views/SimulationView.js +53 -0
  294. package/dist/ui/ink/components/views/SimulationView.js.map +1 -0
  295. package/dist/ui/ink/components/views/TestCaseDetailView.d.ts +11 -0
  296. package/dist/ui/ink/components/views/TestCaseDetailView.js +53 -0
  297. package/dist/ui/ink/components/views/TestCaseDetailView.js.map +1 -0
  298. package/dist/ui/ink/components/views/ToolDetailView.d.ts +15 -0
  299. package/dist/ui/ink/components/views/ToolDetailView.js +25 -0
  300. package/dist/ui/ink/components/views/ToolDetailView.js.map +1 -0
  301. package/dist/ui/ink/components/views/ToolsView.d.ts +15 -0
  302. package/dist/ui/ink/components/views/ToolsView.js +43 -0
  303. package/dist/ui/ink/components/views/ToolsView.js.map +1 -0
  304. package/dist/ui/ink/demo.d.ts +6 -0
  305. package/dist/ui/ink/demo.js +254 -0
  306. package/dist/ui/ink/demo.js.map +1 -0
  307. package/dist/ui/ink/hooks/useAnimation.d.ts +29 -0
  308. package/dist/ui/ink/hooks/useAnimation.js +89 -0
  309. package/dist/ui/ink/hooks/useAnimation.js.map +1 -0
  310. package/dist/ui/ink/hooks/useAudit.d.ts +69 -0
  311. package/dist/ui/ink/hooks/useAudit.js +99 -0
  312. package/dist/ui/ink/hooks/useAudit.js.map +1 -0
  313. package/dist/ui/ink/hooks/useCrawlAnimation.d.ts +19 -0
  314. package/dist/ui/ink/hooks/useCrawlAnimation.js +204 -0
  315. package/dist/ui/ink/hooks/useCrawlAnimation.js.map +1 -0
  316. package/dist/ui/ink/hooks/useKeyboardNav.d.ts +23 -0
  317. package/dist/ui/ink/hooks/useKeyboardNav.js +81 -0
  318. package/dist/ui/ink/hooks/useKeyboardNav.js.map +1 -0
  319. package/dist/ui/ink/hooks/useNavigation.d.ts +16 -0
  320. package/dist/ui/ink/hooks/useNavigation.js +42 -0
  321. package/dist/ui/ink/hooks/useNavigation.js.map +1 -0
  322. package/dist/ui/ink/hooks/useTerminalSize.d.ts +10 -0
  323. package/dist/ui/ink/hooks/useTerminalSize.js +29 -0
  324. package/dist/ui/ink/hooks/useTerminalSize.js.map +1 -0
  325. package/dist/ui/ink/index.d.ts +43 -0
  326. package/dist/ui/ink/index.js +50 -0
  327. package/dist/ui/ink/index.js.map +1 -0
  328. package/dist/ui/ink/render.d.ts +24 -0
  329. package/dist/ui/ink/render.js +14 -0
  330. package/dist/ui/ink/render.js.map +1 -0
  331. package/dist/ui/ink/theme.d.ts +37 -0
  332. package/dist/ui/ink/theme.js +38 -0
  333. package/dist/ui/ink/theme.js.map +1 -0
  334. package/dist/ui/ink/types.d.ts +77 -0
  335. package/dist/ui/ink/types.js +5 -0
  336. package/dist/ui/ink/types.js.map +1 -0
  337. package/dist/ui/score-display.d.ts +16 -0
  338. package/dist/ui/score-display.js +201 -0
  339. package/dist/ui/score-display.js.map +1 -0
  340. package/dist/ui/spinner.d.ts +45 -0
  341. package/dist/ui/spinner.js +112 -0
  342. package/dist/ui/spinner.js.map +1 -0
  343. package/dist/ui/utils.d.ts +13 -0
  344. package/dist/ui/utils.js +25 -0
  345. package/dist/ui/utils.js.map +1 -0
  346. package/package.json +61 -9
  347. package/index.js +0 -105
@@ -0,0 +1,233 @@
1
+ /**
2
+ * LLM Types
3
+ *
4
+ * Type definitions for LLM-based rule evaluation.
5
+ */
6
+ import type { DetectedTool } from '../core/types/tool.js';
7
+ /**
8
+ * LLM Provider configuration
9
+ */
10
+ export interface LLMConfig {
11
+ /**
12
+ * API key for the LLM provider
13
+ */
14
+ apiKey: string;
15
+ /**
16
+ * Model identifier (e.g., 'anthropic/claude-sonnet-4.5')
17
+ */
18
+ model: string;
19
+ /**
20
+ * Base URL for the API (e.g., OpenRouter endpoint)
21
+ */
22
+ baseUrl?: string;
23
+ /**
24
+ * Temperature for generation (0-1)
25
+ */
26
+ temperature?: number;
27
+ /**
28
+ * Maximum tokens to generate
29
+ */
30
+ maxTokens?: number;
31
+ }
32
+ /**
33
+ * Context provided to LLM for evaluation
34
+ */
35
+ export interface EvaluationContext {
36
+ /**
37
+ * The tool being evaluated
38
+ */
39
+ tool: DetectedTool;
40
+ /**
41
+ * The specific question/prompt for evaluation
42
+ */
43
+ question: string;
44
+ /**
45
+ * Evaluation criteria to check
46
+ */
47
+ criteria: string[];
48
+ /**
49
+ * Additional context (e.g., other tools on the page)
50
+ */
51
+ additionalContext?: string;
52
+ }
53
+ /**
54
+ * Result from LLM evaluation
55
+ */
56
+ export interface EvaluationResult {
57
+ /**
58
+ * Whether the evaluation passed
59
+ */
60
+ passed: boolean;
61
+ /**
62
+ * Score from 0-10
63
+ */
64
+ score: number;
65
+ /**
66
+ * LLM's reasoning for the evaluation
67
+ */
68
+ reasoning: string;
69
+ /**
70
+ * Specific issues found
71
+ */
72
+ issues?: string[];
73
+ /**
74
+ * Suggestions for improvement
75
+ */
76
+ suggestions?: string[];
77
+ /**
78
+ * Raw LLM response (for debugging)
79
+ */
80
+ rawResponse?: string;
81
+ /**
82
+ * Whether this result came from cache
83
+ */
84
+ cached?: boolean;
85
+ }
86
+ /**
87
+ * Description quality evaluation context
88
+ */
89
+ export interface DescriptionEvalContext {
90
+ /**
91
+ * Tool name
92
+ */
93
+ name: string;
94
+ /**
95
+ * Tool description
96
+ */
97
+ description: string;
98
+ /**
99
+ * Input schema (stringified)
100
+ */
101
+ inputSchema?: string;
102
+ /**
103
+ * What aspect to evaluate
104
+ */
105
+ aspect: 'clarity' | 'specificity' | 'positive-framing' | 'completeness' | 'steering' | 'atomicity' | 'similarity' | 'all';
106
+ }
107
+ /**
108
+ * Full description quality report
109
+ */
110
+ export interface DescriptionQualityReport {
111
+ /**
112
+ * Overall quality score (0-100)
113
+ */
114
+ overallScore: number;
115
+ /**
116
+ * Individual aspect scores
117
+ */
118
+ aspects: {
119
+ clarity: EvaluationResult;
120
+ specificity: EvaluationResult;
121
+ positiveFraming: EvaluationResult;
122
+ completeness: EvaluationResult;
123
+ steeringPerformance: EvaluationResult;
124
+ atomicity: EvaluationResult;
125
+ };
126
+ /**
127
+ * Overall assessment
128
+ */
129
+ summary: string;
130
+ /**
131
+ * Top priority improvements
132
+ */
133
+ priorityImprovements: string[];
134
+ /**
135
+ * Suggested rewritten description
136
+ */
137
+ suggestedDescription?: string;
138
+ }
139
+ /**
140
+ * LLM Provider interface
141
+ */
142
+ export interface LLMProvider {
143
+ /**
144
+ * Provider name
145
+ */
146
+ name: string;
147
+ /**
148
+ * Send a prompt and get a response
149
+ */
150
+ complete(prompt: string, systemPrompt?: string): Promise<string>;
151
+ /**
152
+ * Evaluate a tool description
153
+ */
154
+ evaluateDescription(context: DescriptionEvalContext): Promise<EvaluationResult>;
155
+ /**
156
+ * Get a full quality report for a tool
157
+ */
158
+ getQualityReport(tool: DetectedTool): Promise<DescriptionQualityReport>;
159
+ /**
160
+ * Check if the provider is available (has valid credentials)
161
+ */
162
+ isAvailable(): boolean;
163
+ }
164
+ export interface EvaluationCacheEntry {
165
+ kind: 'evaluation';
166
+ result: EvaluationResult;
167
+ timestamp: number;
168
+ inputHash: string;
169
+ }
170
+ export interface ReportCacheEntry {
171
+ kind: 'report';
172
+ result: DescriptionQualityReport;
173
+ timestamp: number;
174
+ inputHash: string;
175
+ }
176
+ /**
177
+ * Cache entry for LLM evaluations/reports.
178
+ */
179
+ export type CacheEntry = EvaluationCacheEntry | ReportCacheEntry;
180
+ /**
181
+ * Cache storage structure
182
+ */
183
+ export interface LLMCache {
184
+ /**
185
+ * Version for cache invalidation
186
+ */
187
+ version: number;
188
+ /**
189
+ * Cached entries by key
190
+ */
191
+ entries: Record<string, CacheEntry>;
192
+ }
193
+ /**
194
+ * Evaluation types for different rules
195
+ */
196
+ export type EvaluationType = 'desc-specific-verb' | 'desc-positive-framing' | 'desc-explains-what' | 'desc-explains-when' | 'bp-atomic-tool' | 'steering-quality' | 'instruction-similarity' | 'param-clarity' | 'full-quality';
197
+ /**
198
+ * LLM-generated smart advice for a finding
199
+ */
200
+ export interface SmartAdvice {
201
+ currentState: {
202
+ description: string;
203
+ problemAreas: string[];
204
+ agentImpact: string;
205
+ };
206
+ enhanced: {
207
+ suggestedFix: string;
208
+ explanation: string;
209
+ codeExample?: string;
210
+ };
211
+ benefits: {
212
+ title: string;
213
+ items: string[];
214
+ };
215
+ confidence: number;
216
+ cached?: boolean;
217
+ }
218
+ /**
219
+ * Finding with optional smart advice attached
220
+ */
221
+ export interface FindingWithAdvice {
222
+ id: string;
223
+ ruleId: string;
224
+ severity: 'critical' | 'warning' | 'info';
225
+ message: string;
226
+ tool?: string;
227
+ page?: string;
228
+ fix?: string;
229
+ scoreImpact?: number;
230
+ advice?: SmartAdvice;
231
+ adviceLoading?: boolean;
232
+ adviceError?: string;
233
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * LLM Types
3
+ *
4
+ * Type definitions for LLM-based rule evaluation.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/llm/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * BP-001: Annotations Present
3
+ *
4
+ * Checks if tools have an annotations object defined.
5
+ * Annotations provide important hints about tool behavior
6
+ * (readOnlyHint, destructiveHint, etc.) that help agents
7
+ * make better decisions.
8
+ */
9
+ import type { Rule } from '../../core/types/rule.js';
10
+ export declare const BP_001: Rule;
11
+ export default BP_001;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * BP-001: Annotations Present
3
+ *
4
+ * Checks if tools have an annotations object defined.
5
+ * Annotations provide important hints about tool behavior
6
+ * (readOnlyHint, destructiveHint, etc.) that help agents
7
+ * make better decisions.
8
+ */
9
+ import { createRuleResult } from '../runner.js';
10
+ export const BP_001 = {
11
+ id: 'BP-001',
12
+ category: 'best-practices',
13
+ name: 'Annotations Present',
14
+ description: 'Tools should have an annotations object for behavior hints',
15
+ severity: 'info',
16
+ maxScore: 5,
17
+ async check(context) {
18
+ const tools = context.tools;
19
+ if (tools.length === 0) {
20
+ return createRuleResult('BP-001', 5, {
21
+ passed: true,
22
+ score: 5,
23
+ message: 'No tools detected (rule not applicable)',
24
+ });
25
+ }
26
+ const toolsWithoutAnnotations = [];
27
+ for (const tool of tools) {
28
+ if (!tool.annotations || Object.keys(tool.annotations).length === 0) {
29
+ toolsWithoutAnnotations.push(tool.name);
30
+ }
31
+ }
32
+ if (toolsWithoutAnnotations.length === 0) {
33
+ return createRuleResult('BP-001', 5, {
34
+ passed: true,
35
+ score: 5,
36
+ message: `All ${tools.length} tool(s) have annotations defined`,
37
+ });
38
+ }
39
+ // Deduct 1 point per tool missing annotations, minimum 0
40
+ const penalty = Math.min(toolsWithoutAnnotations.length, 5);
41
+ const score = Math.max(0, 5 - penalty);
42
+ return createRuleResult('BP-001', 5, {
43
+ passed: false,
44
+ score,
45
+ message: `${toolsWithoutAnnotations.length} tool(s) missing annotations`,
46
+ details: toolsWithoutAnnotations.map((name) => `Tool "${name}" has no annotations object`),
47
+ suggestions: [
48
+ 'Add annotations object with readOnlyHint, destructiveHint, etc.',
49
+ 'Example: { annotations: { readOnlyHint: true } }',
50
+ ],
51
+ affectedTools: toolsWithoutAnnotations,
52
+ });
53
+ },
54
+ };
55
+ export default BP_001;
56
+ //# sourceMappingURL=BP-001.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BP-001.js","sourceRoot":"","sources":["../../../src/rules/best-practices/BP-001.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,CAAC,MAAM,MAAM,GAAS;IAC1B,EAAE,EAAE,QAAQ;IACZ,QAAQ,EAAE,gBAAgB;IAC1B,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EAAE,4DAA4D;IACzE,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,CAAC;IAEX,KAAK,CAAC,KAAK,CAAC,OAAoB;QAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAE5B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,gBAAgB,CAAC,QAAQ,EAAE,CAAC,EAAE;gBACnC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,yCAAyC;aACnD,CAAC,CAAC;QACL,CAAC;QAED,MAAM,uBAAuB,GAAa,EAAE,CAAC;QAE7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACpE,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QAED,IAAI,uBAAuB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzC,OAAO,gBAAgB,CAAC,QAAQ,EAAE,CAAC,EAAE;gBACnC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,OAAO,KAAK,CAAC,MAAM,mCAAmC;aAChE,CAAC,CAAC;QACL,CAAC;QAED,yDAAyD;QACzD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC;QAEvC,OAAO,gBAAgB,CAAC,QAAQ,EAAE,CAAC,EAAE;YACnC,MAAM,EAAE,KAAK;YACb,KAAK;YACL,OAAO,EAAE,GAAG,uBAAuB,CAAC,MAAM,8BAA8B;YACxE,OAAO,EAAE,uBAAuB,CAAC,GAAG,CAClC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,IAAI,6BAA6B,CACrD;YACD,WAAW,EAAE;gBACX,iEAAiE;gBACjE,kDAAkD;aACnD;YACD,aAAa,EAAE,uBAAuB;SACvC,CAAC,CAAC;IACL,CAAC;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * BP-002: Destructive Hint Used
3
+ *
4
+ * Checks if tools with destructive-sounding names/descriptions
5
+ * have the destructiveHint annotation set to true.
6
+ *
7
+ * Destructive operations include: delete, remove, purchase, cancel, etc.
8
+ */
9
+ import type { Rule } from '../../core/types/rule.js';
10
+ export declare const BP_002: Rule;
11
+ export default BP_002;
@@ -0,0 +1,63 @@
1
+ /**
2
+ * BP-002: Destructive Hint Used
3
+ *
4
+ * Checks if tools with destructive-sounding names/descriptions
5
+ * have the destructiveHint annotation set to true.
6
+ *
7
+ * Destructive operations include: delete, remove, purchase, cancel, etc.
8
+ */
9
+ import { createRuleResult } from '../runner.js';
10
+ import { DESTRUCTIVE_KEYWORDS, hasKeyword, findMatchedKeywords, } from '../utils/keywords.js';
11
+ export const BP_002 = {
12
+ id: 'BP-002',
13
+ category: 'best-practices',
14
+ name: 'Destructive Hint Used',
15
+ description: 'Tools with destructive operations should have destructiveHint: true',
16
+ severity: 'warning',
17
+ maxScore: 8,
18
+ async check(context) {
19
+ const tools = context.tools;
20
+ if (tools.length === 0) {
21
+ return createRuleResult('BP-002', 8, {
22
+ passed: true,
23
+ score: 8,
24
+ message: 'No tools detected (rule not applicable)',
25
+ });
26
+ }
27
+ const violations = [];
28
+ for (const tool of tools) {
29
+ const textToSearch = `${tool.name} ${tool.description}`;
30
+ if (hasKeyword(textToSearch, DESTRUCTIVE_KEYWORDS)) {
31
+ // Check if destructiveHint is set
32
+ const hasDestructiveHint = tool.annotations?.destructiveHint === true;
33
+ if (!hasDestructiveHint) {
34
+ const matchedKeywords = findMatchedKeywords(textToSearch, DESTRUCTIVE_KEYWORDS);
35
+ violations.push({ name: tool.name, keywords: matchedKeywords });
36
+ }
37
+ }
38
+ }
39
+ if (violations.length === 0) {
40
+ return createRuleResult('BP-002', 8, {
41
+ passed: true,
42
+ score: 8,
43
+ message: 'All destructive-looking tools have destructiveHint annotation',
44
+ });
45
+ }
46
+ // Deduct 2 points per violation
47
+ const penalty = violations.length * 2;
48
+ const score = Math.max(0, 8 - penalty);
49
+ return createRuleResult('BP-002', 8, {
50
+ passed: false,
51
+ score,
52
+ message: `${violations.length} tool(s) with destructive keywords missing destructiveHint`,
53
+ details: violations.map((v) => `Tool "${v.name}" contains keywords [${v.keywords.join(', ')}] but lacks destructiveHint: true`),
54
+ suggestions: [
55
+ 'Add destructiveHint: true to annotations for tools that modify/delete data',
56
+ 'Example: { annotations: { destructiveHint: true } }',
57
+ ],
58
+ affectedTools: violations.map((v) => v.name),
59
+ });
60
+ },
61
+ };
62
+ export default BP_002;
63
+ //# sourceMappingURL=BP-002.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BP-002.js","sourceRoot":"","sources":["../../../src/rules/best-practices/BP-002.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,CAAC,MAAM,MAAM,GAAS;IAC1B,EAAE,EAAE,QAAQ;IACZ,QAAQ,EAAE,gBAAgB;IAC1B,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EAAE,qEAAqE;IAClF,QAAQ,EAAE,SAAS;IACnB,QAAQ,EAAE,CAAC;IAEX,KAAK,CAAC,KAAK,CAAC,OAAoB;QAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAE5B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,gBAAgB,CAAC,QAAQ,EAAE,CAAC,EAAE;gBACnC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,yCAAyC;aACnD,CAAC,CAAC;QACL,CAAC;QAED,MAAM,UAAU,GAA2C,EAAE,CAAC;QAE9D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,YAAY,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAExD,IAAI,UAAU,CAAC,YAAY,EAAE,oBAAoB,CAAC,EAAE,CAAC;gBACnD,kCAAkC;gBAClC,MAAM,kBAAkB,GAAG,IAAI,CAAC,WAAW,EAAE,eAAe,KAAK,IAAI,CAAC;gBAEtE,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBACxB,MAAM,eAAe,GAAG,mBAAmB,CACzC,YAAY,EACZ,oBAAoB,CACrB,CAAC;oBACF,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,CAAC;gBAClE,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,gBAAgB,CAAC,QAAQ,EAAE,CAAC,EAAE;gBACnC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,+DAA+D;aACzE,CAAC,CAAC;QACL,CAAC;QAED,gCAAgC;QAChC,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC;QAEvC,OAAO,gBAAgB,CAAC,QAAQ,EAAE,CAAC,EAAE;YACnC,MAAM,EAAE,KAAK;YACb,KAAK;YACL,OAAO,EAAE,GAAG,UAAU,CAAC,MAAM,4DAA4D;YACzF,OAAO,EAAE,UAAU,CAAC,GAAG,CACrB,CAAC,CAAC,EAAE,EAAE,CACJ,SAAS,CAAC,CAAC,IAAI,wBAAwB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,mCAAmC,CAClG;YACD,WAAW,EAAE;gBACX,4EAA4E;gBAC5E,qDAAqD;aACtD;YACD,aAAa,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAC7C,CAAC,CAAC;IACL,CAAC;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * BP-003: ReadOnly Hint Consistency
3
+ *
4
+ * Checks if tools with read-only-sounding names/descriptions
5
+ * have the readOnlyHint annotation set to true.
6
+ *
7
+ * Read-only operations include: get, search, list, fetch, view, etc.
8
+ */
9
+ import type { Rule } from '../../core/types/rule.js';
10
+ export declare const BP_003: Rule;
11
+ export default BP_003;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * BP-003: ReadOnly Hint Consistency
3
+ *
4
+ * Checks if tools with read-only-sounding names/descriptions
5
+ * have the readOnlyHint annotation set to true.
6
+ *
7
+ * Read-only operations include: get, search, list, fetch, view, etc.
8
+ */
9
+ import { createRuleResult } from '../runner.js';
10
+ import { READONLY_KEYWORDS, DESTRUCTIVE_KEYWORDS, hasKeyword, findMatchedKeywords, } from '../utils/keywords.js';
11
+ export const BP_003 = {
12
+ id: 'BP-003',
13
+ category: 'best-practices',
14
+ name: 'ReadOnly Hint Consistency',
15
+ description: 'Tools with read-only operations should have readOnlyHint: true',
16
+ severity: 'info',
17
+ maxScore: 5,
18
+ async check(context) {
19
+ const tools = context.tools;
20
+ if (tools.length === 0) {
21
+ return createRuleResult('BP-003', 5, {
22
+ passed: true,
23
+ score: 5,
24
+ message: 'No tools detected (rule not applicable)',
25
+ });
26
+ }
27
+ const violations = [];
28
+ for (const tool of tools) {
29
+ const textToSearch = `${tool.name} ${tool.description}`;
30
+ // Check if tool looks read-only
31
+ if (hasKeyword(textToSearch, READONLY_KEYWORDS)) {
32
+ // Skip if it also has destructive keywords (ambiguous)
33
+ if (hasKeyword(textToSearch, DESTRUCTIVE_KEYWORDS)) {
34
+ continue;
35
+ }
36
+ // Check if readOnlyHint is set
37
+ const hasReadOnlyHint = tool.annotations?.readOnlyHint === true;
38
+ if (!hasReadOnlyHint) {
39
+ const matchedKeywords = findMatchedKeywords(textToSearch, READONLY_KEYWORDS);
40
+ violations.push({ name: tool.name, keywords: matchedKeywords });
41
+ }
42
+ }
43
+ }
44
+ if (violations.length === 0) {
45
+ return createRuleResult('BP-003', 5, {
46
+ passed: true,
47
+ score: 5,
48
+ message: 'All read-only-looking tools have readOnlyHint annotation',
49
+ });
50
+ }
51
+ // Deduct 1 point per violation
52
+ const penalty = Math.min(violations.length, 5);
53
+ const score = Math.max(0, 5 - penalty);
54
+ return createRuleResult('BP-003', 5, {
55
+ passed: false,
56
+ score,
57
+ message: `${violations.length} tool(s) with read-only keywords missing readOnlyHint`,
58
+ details: violations.map((v) => `Tool "${v.name}" contains keywords [${v.keywords.join(', ')}] but lacks readOnlyHint: true`),
59
+ suggestions: [
60
+ 'Add readOnlyHint: true to annotations for tools that only read data',
61
+ 'Example: { annotations: { readOnlyHint: true } }',
62
+ ],
63
+ affectedTools: violations.map((v) => v.name),
64
+ });
65
+ },
66
+ };
67
+ export default BP_003;
68
+ //# sourceMappingURL=BP-003.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BP-003.js","sourceRoot":"","sources":["../../../src/rules/best-practices/BP-003.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,UAAU,EACV,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,CAAC,MAAM,MAAM,GAAS;IAC1B,EAAE,EAAE,QAAQ;IACZ,QAAQ,EAAE,gBAAgB;IAC1B,IAAI,EAAE,2BAA2B;IACjC,WAAW,EAAE,gEAAgE;IAC7E,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,CAAC;IAEX,KAAK,CAAC,KAAK,CAAC,OAAoB;QAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAE5B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,gBAAgB,CAAC,QAAQ,EAAE,CAAC,EAAE;gBACnC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,yCAAyC;aACnD,CAAC,CAAC;QACL,CAAC;QAED,MAAM,UAAU,GAA2C,EAAE,CAAC;QAE9D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,YAAY,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAExD,gCAAgC;YAChC,IAAI,UAAU,CAAC,YAAY,EAAE,iBAAiB,CAAC,EAAE,CAAC;gBAChD,uDAAuD;gBACvD,IAAI,UAAU,CAAC,YAAY,EAAE,oBAAoB,CAAC,EAAE,CAAC;oBACnD,SAAS;gBACX,CAAC;gBAED,+BAA+B;gBAC/B,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,YAAY,KAAK,IAAI,CAAC;gBAEhE,IAAI,CAAC,eAAe,EAAE,CAAC;oBACrB,MAAM,eAAe,GAAG,mBAAmB,CACzC,YAAY,EACZ,iBAAiB,CAClB,CAAC;oBACF,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,CAAC;gBAClE,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,gBAAgB,CAAC,QAAQ,EAAE,CAAC,EAAE;gBACnC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,0DAA0D;aACpE,CAAC,CAAC;QACL,CAAC;QAED,+BAA+B;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC;QAEvC,OAAO,gBAAgB,CAAC,QAAQ,EAAE,CAAC,EAAE;YACnC,MAAM,EAAE,KAAK;YACb,KAAK;YACL,OAAO,EAAE,GAAG,UAAU,CAAC,MAAM,uDAAuD;YACpF,OAAO,EAAE,UAAU,CAAC,GAAG,CACrB,CAAC,CAAC,EAAE,EAAE,CACJ,SAAS,CAAC,CAAC,IAAI,wBAAwB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,gCAAgC,CAC/F;YACD,WAAW,EAAE;gBACX,qEAAqE;gBACrE,kDAAkD;aACnD;YACD,aAAa,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAC7C,CAAC,CAAC;IACL,CAAC;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * COV-001: Form Coverage
3
+ *
4
+ * Checks if all interactive forms on the page are exposed as MCP tools.
5
+ * Unregistered forms represent missed opportunities for tool coverage.
6
+ */
7
+ import type { Rule } from '../../core/types/rule.js';
8
+ export declare const COV_001: Rule;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * COV-001: Form Coverage
3
+ *
4
+ * Checks if all interactive forms on the page are exposed as MCP tools.
5
+ * Unregistered forms represent missed opportunities for tool coverage.
6
+ */
7
+ import { createRuleResult } from '../runner.js';
8
+ export const COV_001 = {
9
+ id: 'COV-001',
10
+ category: 'coverage',
11
+ name: 'Form Coverage',
12
+ description: 'All interactive forms should be exposed as MCP tools',
13
+ severity: 'warning',
14
+ maxScore: 5,
15
+ async check(context) {
16
+ const { tools, opportunities } = context;
17
+ if (tools.length === 0 && opportunities.length === 0) {
18
+ return createRuleResult('COV-001', 5, {
19
+ passed: true,
20
+ score: 5,
21
+ message: 'No tools or forms detected (rule not applicable)',
22
+ });
23
+ }
24
+ if (opportunities.length === 0) {
25
+ return createRuleResult('COV-001', 5, {
26
+ passed: true,
27
+ score: 5,
28
+ message: 'All detected forms are covered by MCP tools',
29
+ });
30
+ }
31
+ const totalForms = tools.length + opportunities.length;
32
+ const coverageRatio = tools.length / totalForms;
33
+ const score = Math.round(coverageRatio * 5);
34
+ const passed = opportunities.length === 0;
35
+ const uncoveredNames = opportunities.map((o) => o.contextClues.submitText ||
36
+ o.contextClues.ariaLabel ||
37
+ o.contextClues.formId ||
38
+ o.contextClues.formAction ||
39
+ 'unnamed form');
40
+ return createRuleResult('COV-001', 5, {
41
+ passed,
42
+ score,
43
+ message: `${tools.length}/${totalForms} forms covered (${Math.round(coverageRatio * 100)}%)`,
44
+ details: uncoveredNames.map((n) => `Uncovered form: ${n}`),
45
+ suggestions: opportunities.length > 0
46
+ ? ['Register uncovered forms as MCP tools to improve coverage']
47
+ : undefined,
48
+ });
49
+ },
50
+ };
51
+ //# sourceMappingURL=COV-001.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"COV-001.js","sourceRoot":"","sources":["../../../src/rules/coverage/COV-001.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,CAAC,MAAM,OAAO,GAAS;IAC3B,EAAE,EAAE,SAAS;IACb,QAAQ,EAAE,UAAU;IACpB,IAAI,EAAE,eAAe;IACrB,WAAW,EAAE,sDAAsD;IACnE,QAAQ,EAAE,SAAS;IACnB,QAAQ,EAAE,CAAC;IAEX,KAAK,CAAC,KAAK,CAAC,OAAoB;QAC9B,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;QAEzC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrD,OAAO,gBAAgB,CAAC,SAAS,EAAE,CAAC,EAAE;gBACpC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,kDAAkD;aAC5D,CAAC,CAAC;QACL,CAAC;QAED,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,gBAAgB,CAAC,SAAS,EAAE,CAAC,EAAE;gBACpC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,6CAA6C;aACvD,CAAC,CAAC;QACL,CAAC;QAED,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC;QACvD,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC;QAE1C,MAAM,cAAc,GAAG,aAAa,CAAC,GAAG,CACtC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,YAAY,CAAC,UAAU;YACzB,CAAC,CAAC,YAAY,CAAC,SAAS;YACxB,CAAC,CAAC,YAAY,CAAC,MAAM;YACrB,CAAC,CAAC,YAAY,CAAC,UAAU;YACzB,cAAc,CACjB,CAAC;QAEF,OAAO,gBAAgB,CAAC,SAAS,EAAE,CAAC,EAAE;YACpC,MAAM;YACN,KAAK;YACL,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM,IAAI,UAAU,mBAAmB,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,GAAG,CAAC,IAAI;YAC5F,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC1D,WAAW,EACT,aAAa,CAAC,MAAM,GAAG,CAAC;gBACtB,CAAC,CAAC,CAAC,2DAA2D,CAAC;gBAC/D,CAAC,CAAC,SAAS;SAChB,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * DESC-003: Name Kebab Case
3
+ *
4
+ * Checks if tool names follow snake_case or kebab-case convention.
5
+ * Consistent naming helps agents recognize tools and improves
6
+ * overall API quality.
7
+ *
8
+ * Valid: search_flights, search-flights, search
9
+ * Invalid: searchFlights, SearchFlights
10
+ */
11
+ import type { Rule } from '../../core/types/rule.js';
12
+ export declare const DESC_003: Rule;
13
+ export default DESC_003;
@@ -0,0 +1,96 @@
1
+ /**
2
+ * DESC-003: Name Kebab Case
3
+ *
4
+ * Checks if tool names follow snake_case or kebab-case convention.
5
+ * Consistent naming helps agents recognize tools and improves
6
+ * overall API quality.
7
+ *
8
+ * Valid: search_flights, search-flights, search
9
+ * Invalid: searchFlights, SearchFlights
10
+ */
11
+ import { createRuleResult } from '../runner.js';
12
+ /**
13
+ * Check if a name is in valid format (snake_case, kebab-case, or single word lowercase)
14
+ */
15
+ function isValidToolName(name) {
16
+ // Allow snake_case, kebab-case, or single lowercase word
17
+ // Pattern: lowercase letters, numbers, underscores, and hyphens only
18
+ // Must not have consecutive separators or start/end with separator
19
+ const validPattern = /^[a-z][a-z0-9]*([_-][a-z0-9]+)*$/;
20
+ return validPattern.test(name);
21
+ }
22
+ /**
23
+ * Detect the naming convention used
24
+ */
25
+ function detectNamingIssue(name) {
26
+ if (/[A-Z]/.test(name)) {
27
+ if (/^[A-Z]/.test(name)) {
28
+ return 'PascalCase';
29
+ }
30
+ return 'camelCase';
31
+ }
32
+ if (name.includes(' ')) {
33
+ return 'contains spaces';
34
+ }
35
+ if (/^[_-]|[_-]$/.test(name)) {
36
+ return 'starts or ends with separator';
37
+ }
38
+ if (/[_-]{2,}/.test(name)) {
39
+ return 'consecutive separators';
40
+ }
41
+ return 'invalid format';
42
+ }
43
+ export const DESC_003 = {
44
+ id: 'DESC-003',
45
+ category: 'description',
46
+ name: 'Name Kebab Case',
47
+ description: 'Tool names should use snake_case or kebab-case convention',
48
+ severity: 'warning',
49
+ maxScore: 5,
50
+ async check(context) {
51
+ const tools = context.tools;
52
+ if (tools.length === 0) {
53
+ return createRuleResult('DESC-003', 5, {
54
+ passed: true,
55
+ score: 5,
56
+ message: 'No tools detected (rule not applicable)',
57
+ });
58
+ }
59
+ const violations = [];
60
+ for (const tool of tools) {
61
+ if (!tool.name)
62
+ continue;
63
+ if (!isValidToolName(tool.name)) {
64
+ violations.push({
65
+ name: tool.name,
66
+ issue: detectNamingIssue(tool.name),
67
+ });
68
+ }
69
+ }
70
+ if (violations.length === 0) {
71
+ return createRuleResult('DESC-003', 5, {
72
+ passed: true,
73
+ score: 5,
74
+ message: 'All tool names follow proper naming conventions',
75
+ });
76
+ }
77
+ // Deduct 1 point per violation
78
+ const penalty = Math.min(violations.length, 5);
79
+ const score = Math.max(0, 5 - penalty);
80
+ return createRuleResult('DESC-003', 5, {
81
+ passed: false,
82
+ score,
83
+ message: `${violations.length} tool(s) have naming convention issues`,
84
+ details: violations.map((v) => `Tool "${v.name}" uses ${v.issue}`),
85
+ suggestions: [
86
+ 'Use snake_case: search_flights, get_user_profile',
87
+ 'Or use kebab-case: search-flights, get-user-profile',
88
+ 'Avoid camelCase or PascalCase for tool names',
89
+ 'Consistent naming improves tool discoverability',
90
+ ],
91
+ affectedTools: violations.map((v) => v.name),
92
+ });
93
+ },
94
+ };
95
+ export default DESC_003;
96
+ //# sourceMappingURL=DESC-003.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DESC-003.js","sourceRoot":"","sources":["../../../src/rules/description/DESC-003.ts"],"names":[],"mappings":"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"}