@mseep/core 3.0.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 (312) hide show
  1. package/CHANGELOG.md +285 -0
  2. package/LICENSE +21 -0
  3. package/README.ja.md +14 -0
  4. package/README.ko.md +14 -0
  5. package/README.md +227 -0
  6. package/README.pt-BR.md +14 -0
  7. package/README.skills.md +50 -0
  8. package/README.uk.md +14 -0
  9. package/README.zh-CN.md +14 -0
  10. package/bin/booklib-mcp.js +458 -0
  11. package/bin/booklib.js +2394 -0
  12. package/bin/skills.cjs +1292 -0
  13. package/community/registry.json +1616 -0
  14. package/hooks/hooks.json +52 -0
  15. package/hooks/posttooluse-capture.mjs +67 -0
  16. package/hooks/posttooluse-contradict.mjs +76 -0
  17. package/hooks/posttooluse-imports.mjs +67 -0
  18. package/hooks/pretooluse-inject.mjs +82 -0
  19. package/hooks/suggest.js +153 -0
  20. package/lib/agent-detector.js +96 -0
  21. package/lib/config-loader.js +39 -0
  22. package/lib/conflict-resolver.js +148 -0
  23. package/lib/connectors/context7.js +167 -0
  24. package/lib/connectors/github.js +223 -0
  25. package/lib/connectors/local.js +120 -0
  26. package/lib/connectors/notion.js +436 -0
  27. package/lib/connectors/web.js +134 -0
  28. package/lib/context-builder.js +574 -0
  29. package/lib/discovery-engine.js +298 -0
  30. package/lib/doctor/hook-installer.js +83 -0
  31. package/lib/doctor/usage-tracker.js +87 -0
  32. package/lib/engine/auditor.js +103 -0
  33. package/lib/engine/auto-linker.js +177 -0
  34. package/lib/engine/bm25-index.js +178 -0
  35. package/lib/engine/capture.js +120 -0
  36. package/lib/engine/context-map.js +641 -0
  37. package/lib/engine/corrections.js +194 -0
  38. package/lib/engine/decision-checker.js +203 -0
  39. package/lib/engine/doctor.js +207 -0
  40. package/lib/engine/embedding-provider.js +72 -0
  41. package/lib/engine/gap-detector.js +138 -0
  42. package/lib/engine/gap-resolver.js +135 -0
  43. package/lib/engine/graph-injector.js +137 -0
  44. package/lib/engine/graph-search.js +183 -0
  45. package/lib/engine/graph.js +170 -0
  46. package/lib/engine/handoff.js +411 -0
  47. package/lib/engine/import-checker.js +249 -0
  48. package/lib/engine/import-parser.js +145 -0
  49. package/lib/engine/indexer.js +334 -0
  50. package/lib/engine/lookup-priority.js +15 -0
  51. package/lib/engine/parser.js +257 -0
  52. package/lib/engine/principle-extractor.js +116 -0
  53. package/lib/engine/project-analyzer.js +353 -0
  54. package/lib/engine/query-expander.js +42 -0
  55. package/lib/engine/reasoning-modes.js +353 -0
  56. package/lib/engine/registries.js +524 -0
  57. package/lib/engine/reranker.js +45 -0
  58. package/lib/engine/rrf.js +59 -0
  59. package/lib/engine/scanner.js +151 -0
  60. package/lib/engine/searcher.js +223 -0
  61. package/lib/engine/session-coordinator.js +291 -0
  62. package/lib/engine/session-manager.js +375 -0
  63. package/lib/engine/source-detector.js +240 -0
  64. package/lib/engine/source-manager.js +142 -0
  65. package/lib/engine/structured-response.js +47 -0
  66. package/lib/engine/synthesis-templates.js +364 -0
  67. package/lib/installer.js +70 -0
  68. package/lib/instinct-block.js +21 -0
  69. package/lib/mcp-config-writer.js +107 -0
  70. package/lib/paths.js +62 -0
  71. package/lib/project-initializer.js +856 -0
  72. package/lib/registry/skills.js +102 -0
  73. package/lib/registry-searcher.js +107 -0
  74. package/lib/rules/rules-manager.js +169 -0
  75. package/lib/skill-fetcher.js +333 -0
  76. package/lib/well-known-builder.js +74 -0
  77. package/lib/wizard/index.js +1389 -0
  78. package/lib/wizard/integration-detector.js +41 -0
  79. package/lib/wizard/project-detector.js +146 -0
  80. package/lib/wizard/prompt.js +221 -0
  81. package/lib/wizard/registry-embeddings.js +107 -0
  82. package/lib/wizard/skill-recommender.js +69 -0
  83. package/package.json +70 -0
  84. package/skills/animation-at-work/SKILL.md +270 -0
  85. package/skills/animation-at-work/assets/example_asset.txt +1 -0
  86. package/skills/animation-at-work/evals/evals.json +44 -0
  87. package/skills/animation-at-work/evals/results.json +13 -0
  88. package/skills/animation-at-work/examples/after.md +64 -0
  89. package/skills/animation-at-work/examples/before.md +35 -0
  90. package/skills/animation-at-work/references/api_reference.md +369 -0
  91. package/skills/animation-at-work/references/review-checklist.md +79 -0
  92. package/skills/animation-at-work/scripts/audit_animations.py +295 -0
  93. package/skills/animation-at-work/scripts/example.py +1 -0
  94. package/skills/booklib-mcp-guide/SKILL.md +129 -0
  95. package/skills/booklib-mcp-guide/evals/evals.json +37 -0
  96. package/skills/booklib-mcp-guide/examples/after.md +34 -0
  97. package/skills/booklib-mcp-guide/examples/before.md +27 -0
  98. package/skills/booklib-mcp-guide/references/tool-catalog.md +9 -0
  99. package/skills/clean-code-reviewer/SKILL.md +444 -0
  100. package/skills/clean-code-reviewer/audit.json +35 -0
  101. package/skills/clean-code-reviewer/evals/evals.json +185 -0
  102. package/skills/clean-code-reviewer/evals/results.json +13 -0
  103. package/skills/clean-code-reviewer/examples/after.md +48 -0
  104. package/skills/clean-code-reviewer/examples/before.md +33 -0
  105. package/skills/clean-code-reviewer/references/api_reference.md +158 -0
  106. package/skills/clean-code-reviewer/references/practices-catalog.md +282 -0
  107. package/skills/clean-code-reviewer/references/review-checklist.md +254 -0
  108. package/skills/clean-code-reviewer/scripts/pre-review.py +206 -0
  109. package/skills/data-intensive-patterns/SKILL.md +267 -0
  110. package/skills/data-intensive-patterns/assets/example_asset.txt +1 -0
  111. package/skills/data-intensive-patterns/evals/evals.json +54 -0
  112. package/skills/data-intensive-patterns/evals/results.json +13 -0
  113. package/skills/data-intensive-patterns/examples/after.md +61 -0
  114. package/skills/data-intensive-patterns/examples/before.md +38 -0
  115. package/skills/data-intensive-patterns/references/api_reference.md +34 -0
  116. package/skills/data-intensive-patterns/references/patterns-catalog.md +551 -0
  117. package/skills/data-intensive-patterns/references/review-checklist.md +193 -0
  118. package/skills/data-intensive-patterns/scripts/adr.py +213 -0
  119. package/skills/data-intensive-patterns/scripts/example.py +1 -0
  120. package/skills/data-pipelines/SKILL.md +259 -0
  121. package/skills/data-pipelines/assets/example_asset.txt +1 -0
  122. package/skills/data-pipelines/evals/evals.json +45 -0
  123. package/skills/data-pipelines/evals/results.json +13 -0
  124. package/skills/data-pipelines/examples/after.md +97 -0
  125. package/skills/data-pipelines/examples/before.md +37 -0
  126. package/skills/data-pipelines/references/api_reference.md +301 -0
  127. package/skills/data-pipelines/references/review-checklist.md +181 -0
  128. package/skills/data-pipelines/scripts/example.py +1 -0
  129. package/skills/data-pipelines/scripts/new_pipeline.py +444 -0
  130. package/skills/design-patterns/SKILL.md +271 -0
  131. package/skills/design-patterns/assets/example_asset.txt +1 -0
  132. package/skills/design-patterns/evals/evals.json +46 -0
  133. package/skills/design-patterns/evals/results.json +13 -0
  134. package/skills/design-patterns/examples/after.md +52 -0
  135. package/skills/design-patterns/examples/before.md +29 -0
  136. package/skills/design-patterns/references/api_reference.md +1 -0
  137. package/skills/design-patterns/references/patterns-catalog.md +726 -0
  138. package/skills/design-patterns/references/review-checklist.md +173 -0
  139. package/skills/design-patterns/scripts/example.py +1 -0
  140. package/skills/design-patterns/scripts/scaffold.py +807 -0
  141. package/skills/domain-driven-design/SKILL.md +142 -0
  142. package/skills/domain-driven-design/assets/example_asset.txt +1 -0
  143. package/skills/domain-driven-design/evals/evals.json +48 -0
  144. package/skills/domain-driven-design/evals/results.json +13 -0
  145. package/skills/domain-driven-design/examples/after.md +80 -0
  146. package/skills/domain-driven-design/examples/before.md +43 -0
  147. package/skills/domain-driven-design/references/api_reference.md +1 -0
  148. package/skills/domain-driven-design/references/patterns-catalog.md +545 -0
  149. package/skills/domain-driven-design/references/review-checklist.md +158 -0
  150. package/skills/domain-driven-design/scripts/example.py +1 -0
  151. package/skills/domain-driven-design/scripts/scaffold.py +421 -0
  152. package/skills/effective-java/SKILL.md +227 -0
  153. package/skills/effective-java/assets/example_asset.txt +1 -0
  154. package/skills/effective-java/evals/evals.json +46 -0
  155. package/skills/effective-java/evals/results.json +13 -0
  156. package/skills/effective-java/examples/after.md +83 -0
  157. package/skills/effective-java/examples/before.md +37 -0
  158. package/skills/effective-java/references/api_reference.md +1 -0
  159. package/skills/effective-java/references/items-catalog.md +955 -0
  160. package/skills/effective-java/references/review-checklist.md +216 -0
  161. package/skills/effective-java/scripts/checkstyle_setup.py +211 -0
  162. package/skills/effective-java/scripts/example.py +1 -0
  163. package/skills/effective-kotlin/SKILL.md +271 -0
  164. package/skills/effective-kotlin/assets/example_asset.txt +1 -0
  165. package/skills/effective-kotlin/audit.json +29 -0
  166. package/skills/effective-kotlin/evals/evals.json +45 -0
  167. package/skills/effective-kotlin/evals/results.json +13 -0
  168. package/skills/effective-kotlin/examples/after.md +36 -0
  169. package/skills/effective-kotlin/examples/before.md +38 -0
  170. package/skills/effective-kotlin/references/api_reference.md +1 -0
  171. package/skills/effective-kotlin/references/practices-catalog.md +1228 -0
  172. package/skills/effective-kotlin/references/review-checklist.md +126 -0
  173. package/skills/effective-kotlin/scripts/example.py +1 -0
  174. package/skills/effective-python/SKILL.md +441 -0
  175. package/skills/effective-python/evals/evals.json +44 -0
  176. package/skills/effective-python/evals/results.json +13 -0
  177. package/skills/effective-python/examples/after.md +56 -0
  178. package/skills/effective-python/examples/before.md +40 -0
  179. package/skills/effective-python/ref-01-pythonic-thinking.md +202 -0
  180. package/skills/effective-python/ref-02-lists-and-dicts.md +146 -0
  181. package/skills/effective-python/ref-03-functions.md +186 -0
  182. package/skills/effective-python/ref-04-comprehensions-generators.md +211 -0
  183. package/skills/effective-python/ref-05-classes-interfaces.md +188 -0
  184. package/skills/effective-python/ref-06-metaclasses-attributes.md +209 -0
  185. package/skills/effective-python/ref-07-concurrency.md +213 -0
  186. package/skills/effective-python/ref-08-robustness-performance.md +248 -0
  187. package/skills/effective-python/ref-09-testing-debugging.md +253 -0
  188. package/skills/effective-python/ref-10-collaboration.md +175 -0
  189. package/skills/effective-python/references/api_reference.md +218 -0
  190. package/skills/effective-python/references/practices-catalog.md +483 -0
  191. package/skills/effective-python/references/review-checklist.md +190 -0
  192. package/skills/effective-python/scripts/lint.py +173 -0
  193. package/skills/effective-typescript/SKILL.md +262 -0
  194. package/skills/effective-typescript/audit.json +29 -0
  195. package/skills/effective-typescript/evals/evals.json +37 -0
  196. package/skills/effective-typescript/evals/results.json +13 -0
  197. package/skills/effective-typescript/examples/after.md +70 -0
  198. package/skills/effective-typescript/examples/before.md +47 -0
  199. package/skills/effective-typescript/references/api_reference.md +118 -0
  200. package/skills/effective-typescript/references/practices-catalog.md +371 -0
  201. package/skills/effective-typescript/scripts/review.py +169 -0
  202. package/skills/kotlin-in-action/SKILL.md +261 -0
  203. package/skills/kotlin-in-action/assets/example_asset.txt +1 -0
  204. package/skills/kotlin-in-action/evals/evals.json +43 -0
  205. package/skills/kotlin-in-action/evals/results.json +13 -0
  206. package/skills/kotlin-in-action/examples/after.md +53 -0
  207. package/skills/kotlin-in-action/examples/before.md +39 -0
  208. package/skills/kotlin-in-action/references/api_reference.md +1 -0
  209. package/skills/kotlin-in-action/references/practices-catalog.md +436 -0
  210. package/skills/kotlin-in-action/references/review-checklist.md +204 -0
  211. package/skills/kotlin-in-action/scripts/example.py +1 -0
  212. package/skills/kotlin-in-action/scripts/setup_detekt.py +224 -0
  213. package/skills/lean-startup/SKILL.md +160 -0
  214. package/skills/lean-startup/assets/example_asset.txt +1 -0
  215. package/skills/lean-startup/evals/evals.json +43 -0
  216. package/skills/lean-startup/evals/results.json +13 -0
  217. package/skills/lean-startup/examples/after.md +80 -0
  218. package/skills/lean-startup/examples/before.md +34 -0
  219. package/skills/lean-startup/references/api_reference.md +319 -0
  220. package/skills/lean-startup/references/review-checklist.md +137 -0
  221. package/skills/lean-startup/scripts/example.py +1 -0
  222. package/skills/lean-startup/scripts/new_experiment.py +286 -0
  223. package/skills/microservices-patterns/SKILL.md +384 -0
  224. package/skills/microservices-patterns/evals/evals.json +45 -0
  225. package/skills/microservices-patterns/evals/results.json +13 -0
  226. package/skills/microservices-patterns/examples/after.md +69 -0
  227. package/skills/microservices-patterns/examples/before.md +40 -0
  228. package/skills/microservices-patterns/references/patterns-catalog.md +391 -0
  229. package/skills/microservices-patterns/references/review-checklist.md +169 -0
  230. package/skills/microservices-patterns/scripts/new_service.py +583 -0
  231. package/skills/programming-with-rust/SKILL.md +209 -0
  232. package/skills/programming-with-rust/evals/evals.json +37 -0
  233. package/skills/programming-with-rust/evals/results.json +13 -0
  234. package/skills/programming-with-rust/examples/after.md +107 -0
  235. package/skills/programming-with-rust/examples/before.md +59 -0
  236. package/skills/programming-with-rust/references/api_reference.md +152 -0
  237. package/skills/programming-with-rust/references/practices-catalog.md +335 -0
  238. package/skills/programming-with-rust/scripts/review.py +142 -0
  239. package/skills/refactoring-ui/SKILL.md +362 -0
  240. package/skills/refactoring-ui/assets/example_asset.txt +1 -0
  241. package/skills/refactoring-ui/evals/evals.json +45 -0
  242. package/skills/refactoring-ui/evals/results.json +13 -0
  243. package/skills/refactoring-ui/examples/after.md +85 -0
  244. package/skills/refactoring-ui/examples/before.md +58 -0
  245. package/skills/refactoring-ui/references/api_reference.md +355 -0
  246. package/skills/refactoring-ui/references/review-checklist.md +114 -0
  247. package/skills/refactoring-ui/scripts/audit_css.py +250 -0
  248. package/skills/refactoring-ui/scripts/example.py +1 -0
  249. package/skills/rust-in-action/SKILL.md +350 -0
  250. package/skills/rust-in-action/evals/evals.json +38 -0
  251. package/skills/rust-in-action/evals/results.json +13 -0
  252. package/skills/rust-in-action/examples/after.md +156 -0
  253. package/skills/rust-in-action/examples/before.md +56 -0
  254. package/skills/rust-in-action/references/practices-catalog.md +346 -0
  255. package/skills/rust-in-action/scripts/review.py +147 -0
  256. package/skills/skill-router/SKILL.md +186 -0
  257. package/skills/skill-router/evals/evals.json +38 -0
  258. package/skills/skill-router/evals/results.json +13 -0
  259. package/skills/skill-router/examples/after.md +63 -0
  260. package/skills/skill-router/examples/before.md +39 -0
  261. package/skills/skill-router/references/api_reference.md +24 -0
  262. package/skills/skill-router/references/routing-heuristics.md +89 -0
  263. package/skills/skill-router/references/skill-catalog.md +174 -0
  264. package/skills/skill-router/scripts/route.py +266 -0
  265. package/skills/spring-boot-in-action/SKILL.md +340 -0
  266. package/skills/spring-boot-in-action/evals/evals.json +39 -0
  267. package/skills/spring-boot-in-action/evals/results.json +13 -0
  268. package/skills/spring-boot-in-action/examples/after.md +185 -0
  269. package/skills/spring-boot-in-action/examples/before.md +84 -0
  270. package/skills/spring-boot-in-action/references/practices-catalog.md +403 -0
  271. package/skills/spring-boot-in-action/scripts/review.py +184 -0
  272. package/skills/storytelling-with-data/SKILL.md +241 -0
  273. package/skills/storytelling-with-data/assets/example_asset.txt +1 -0
  274. package/skills/storytelling-with-data/evals/evals.json +47 -0
  275. package/skills/storytelling-with-data/evals/results.json +13 -0
  276. package/skills/storytelling-with-data/examples/after.md +50 -0
  277. package/skills/storytelling-with-data/examples/before.md +33 -0
  278. package/skills/storytelling-with-data/references/api_reference.md +379 -0
  279. package/skills/storytelling-with-data/references/review-checklist.md +111 -0
  280. package/skills/storytelling-with-data/scripts/chart_review.py +301 -0
  281. package/skills/storytelling-with-data/scripts/example.py +1 -0
  282. package/skills/system-design-interview/SKILL.md +233 -0
  283. package/skills/system-design-interview/assets/example_asset.txt +1 -0
  284. package/skills/system-design-interview/evals/evals.json +46 -0
  285. package/skills/system-design-interview/evals/results.json +13 -0
  286. package/skills/system-design-interview/examples/after.md +94 -0
  287. package/skills/system-design-interview/examples/before.md +27 -0
  288. package/skills/system-design-interview/references/api_reference.md +582 -0
  289. package/skills/system-design-interview/references/review-checklist.md +201 -0
  290. package/skills/system-design-interview/scripts/example.py +1 -0
  291. package/skills/system-design-interview/scripts/new_design.py +421 -0
  292. package/skills/using-asyncio-python/SKILL.md +290 -0
  293. package/skills/using-asyncio-python/assets/example_asset.txt +1 -0
  294. package/skills/using-asyncio-python/evals/evals.json +43 -0
  295. package/skills/using-asyncio-python/evals/results.json +13 -0
  296. package/skills/using-asyncio-python/examples/after.md +68 -0
  297. package/skills/using-asyncio-python/examples/before.md +39 -0
  298. package/skills/using-asyncio-python/references/api_reference.md +267 -0
  299. package/skills/using-asyncio-python/references/review-checklist.md +149 -0
  300. package/skills/using-asyncio-python/scripts/check_blocking.py +270 -0
  301. package/skills/using-asyncio-python/scripts/example.py +1 -0
  302. package/skills/web-scraping-python/SKILL.md +280 -0
  303. package/skills/web-scraping-python/assets/example_asset.txt +1 -0
  304. package/skills/web-scraping-python/evals/evals.json +46 -0
  305. package/skills/web-scraping-python/evals/results.json +13 -0
  306. package/skills/web-scraping-python/examples/after.md +109 -0
  307. package/skills/web-scraping-python/examples/before.md +40 -0
  308. package/skills/web-scraping-python/references/api_reference.md +393 -0
  309. package/skills/web-scraping-python/references/review-checklist.md +163 -0
  310. package/skills/web-scraping-python/scripts/example.py +1 -0
  311. package/skills/web-scraping-python/scripts/new_scraper.py +231 -0
  312. package/skills/writing-plans/audit.json +34 -0
@@ -0,0 +1,295 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ audit_animations.py - Audit CSS/SCSS for animation anti-patterns.
4
+
5
+ Usage:
6
+ python audit_animations.py <file_or_directory>
7
+
8
+ Scans .css and .scss files for animation anti-patterns documented in
9
+ "Animation at Work" by Rachel Nabors.
10
+
11
+ Checks performed:
12
+ 1. Animating layout-triggering properties (use transform instead)
13
+ 2. transition: all (too broad)
14
+ 3. Transitions > 500ms or animations > 1000ms (too slow)
15
+ 4. Durations < 100ms (too fast to perceive)
16
+ 5. linear easing on UI transitions (use ease-out or cubic-bezier)
17
+ 6. Missing prefers-reduced-motion in files that animate
18
+ 7. infinite animations without a pause mechanism
19
+
20
+ Outputs: file, line, offending CSS, and recommended fix.
21
+ Summary at end: total issues by category.
22
+ """
23
+
24
+ import argparse
25
+ import pathlib
26
+ import re
27
+ import sys
28
+ from collections import defaultdict
29
+ from typing import NamedTuple
30
+
31
+
32
+ class Issue(NamedTuple):
33
+ file: str
34
+ line: int
35
+ category: str
36
+ snippet: str
37
+ advice: str
38
+
39
+
40
+ # Properties that trigger layout recalculation — animating them is expensive.
41
+ LAYOUT_TRIGGERING = [
42
+ "width", "height", "top", "left", "right", "bottom",
43
+ "margin", "margin-top", "margin-right", "margin-bottom", "margin-left",
44
+ "padding", "padding-top", "padding-right", "padding-bottom", "padding-left",
45
+ ]
46
+
47
+ CATEGORIES = {
48
+ "layout_property": "Layout-triggering property animated",
49
+ "transition_all": "transition: all used",
50
+ "too_slow": "Duration too long (sluggish UI)",
51
+ "too_fast": "Duration too short (imperceptible)",
52
+ "linear_easing": "Linear easing on UI transition",
53
+ "no_reduced_motion": "Missing prefers-reduced-motion",
54
+ "infinite_no_pause": "Infinite animation without pause mechanism",
55
+ }
56
+
57
+
58
+ def parse_duration_ms(value: str) -> float | None:
59
+ """Convert a CSS duration string (e.g. '0.3s', '300ms') to milliseconds."""
60
+ value = value.strip()
61
+ if value.endswith("ms"):
62
+ try:
63
+ return float(value[:-2])
64
+ except ValueError:
65
+ return None
66
+ if value.endswith("s"):
67
+ try:
68
+ return float(value[:-1]) * 1000
69
+ except ValueError:
70
+ return None
71
+ return None
72
+
73
+
74
+ def find_css_files(path: pathlib.Path) -> list[pathlib.Path]:
75
+ if path.is_file():
76
+ if path.suffix in {".css", ".scss"}:
77
+ return [path]
78
+ print(f"WARNING: {path} is not a .css or .scss file — skipping.")
79
+ return []
80
+ return sorted(path.rglob("*.css")) + sorted(path.rglob("*.scss"))
81
+
82
+
83
+ def audit_file(filepath: pathlib.Path) -> list[Issue]:
84
+ issues: list[Issue] = []
85
+ try:
86
+ lines = filepath.read_text(encoding="utf-8", errors="replace").splitlines()
87
+ except OSError as exc:
88
+ print(f"ERROR reading {filepath}: {exc}")
89
+ return []
90
+
91
+ file_str = filepath.as_posix()
92
+ full_text = "\n".join(lines)
93
+
94
+ has_animation = bool(
95
+ re.search(r"\b(transition|animation)\s*:", full_text)
96
+ )
97
+ has_reduced_motion = "prefers-reduced-motion" in full_text
98
+
99
+ for lineno, raw_line in enumerate(lines, start=1):
100
+ line = raw_line.strip()
101
+ if not line or line.startswith("//") or line.startswith("/*"):
102
+ continue
103
+
104
+ # 1. Animating layout-triggering properties
105
+ transition_match = re.match(r"transition\s*:\s*(.+)", line, re.IGNORECASE)
106
+ if transition_match:
107
+ props_part = transition_match.group(1)
108
+ for prop in LAYOUT_TRIGGERING:
109
+ if re.search(r"\b" + re.escape(prop) + r"\b", props_part, re.IGNORECASE):
110
+ issues.append(Issue(
111
+ file=file_str,
112
+ line=lineno,
113
+ category="layout_property",
114
+ snippet=line[:120],
115
+ advice=(
116
+ f"Animating '{prop}' triggers layout recalculation on every frame. "
117
+ "Use 'transform: translate/scale' or 'opacity' instead — "
118
+ "these are compositor-only and do not cause reflow."
119
+ ),
120
+ ))
121
+
122
+ # 2. transition: all
123
+ if re.search(r"transition\s*:\s*all\b", line, re.IGNORECASE):
124
+ issues.append(Issue(
125
+ file=file_str,
126
+ line=lineno,
127
+ category="transition_all",
128
+ snippet=line[:120],
129
+ advice=(
130
+ "'transition: all' animates every animatable property, including "
131
+ "layout-triggering ones you may not intend. List specific properties: "
132
+ "e.g., 'transition: opacity 0.2s ease-out, transform 0.2s ease-out'."
133
+ ),
134
+ ))
135
+
136
+ # 3 & 4. Duration checks — transition and animation shorthand
137
+ duration_patterns = [
138
+ re.compile(r"transition\s*:[^;]+", re.IGNORECASE),
139
+ re.compile(r"animation\s*:[^;]+", re.IGNORECASE),
140
+ re.compile(r"transition-duration\s*:\s*([^;]+)", re.IGNORECASE),
141
+ re.compile(r"animation-duration\s*:\s*([^;]+)", re.IGNORECASE),
142
+ ]
143
+ for pat in duration_patterns:
144
+ m = pat.search(line)
145
+ if not m:
146
+ continue
147
+ value_str = m.group(0)
148
+ is_animation = "animation" in value_str.lower() and "transition" not in value_str.lower()
149
+ for dur_match in re.finditer(r"\d+(?:\.\d+)?(?:ms|s)\b", value_str):
150
+ dur_ms = parse_duration_ms(dur_match.group(0))
151
+ if dur_ms is None:
152
+ continue
153
+ slow_limit = 1000 if is_animation else 500
154
+ if dur_ms > slow_limit:
155
+ issues.append(Issue(
156
+ file=file_str,
157
+ line=lineno,
158
+ category="too_slow",
159
+ snippet=line[:120],
160
+ advice=(
161
+ f"Duration {dur_ms:.0f}ms feels sluggish for UI feedback. "
162
+ f"Keep UI transitions under {slow_limit}ms. "
163
+ "Aim for 200-300ms for most interactions."
164
+ ),
165
+ ))
166
+ elif dur_ms < 100 and dur_ms > 0:
167
+ issues.append(Issue(
168
+ file=file_str,
169
+ line=lineno,
170
+ category="too_fast",
171
+ snippet=line[:120],
172
+ advice=(
173
+ f"Duration {dur_ms:.0f}ms is below the human perception threshold (~100ms). "
174
+ "The animation will not be noticed. Use 100-200ms for snappy transitions."
175
+ ),
176
+ ))
177
+
178
+ # 5. Linear easing on transitions
179
+ if re.search(r"transition\s*:", line, re.IGNORECASE):
180
+ if re.search(r"\blinear\b", line, re.IGNORECASE):
181
+ issues.append(Issue(
182
+ file=file_str,
183
+ line=lineno,
184
+ category="linear_easing",
185
+ snippet=line[:120],
186
+ advice=(
187
+ "Linear easing feels mechanical and unnatural for UI elements. "
188
+ "Use 'ease-out' for elements entering the screen, 'ease-in' for "
189
+ "elements leaving, or a custom cubic-bezier for branded motion."
190
+ ),
191
+ ))
192
+
193
+ # 7. Infinite animation without pause mechanism
194
+ if re.search(r"animation-iteration-count\s*:\s*infinite\b", line, re.IGNORECASE):
195
+ # Check nearby lines (±10) for a paused state or play-state control
196
+ start = max(0, lineno - 10)
197
+ end = min(len(lines), lineno + 10)
198
+ context_block = "\n".join(lines[start:end])
199
+ if "animation-play-state" not in context_block and "paused" not in context_block:
200
+ issues.append(Issue(
201
+ file=file_str,
202
+ line=lineno,
203
+ category="infinite_no_pause",
204
+ snippet=line[:120],
205
+ advice=(
206
+ "Infinite animations can be distracting and drain battery on mobile. "
207
+ "Add 'animation-play-state: paused' controlled via :hover, :focus, "
208
+ "or a JS toggle so users can pause it."
209
+ ),
210
+ ))
211
+
212
+ # 6. Missing prefers-reduced-motion
213
+ if has_animation and not has_reduced_motion:
214
+ issues.append(Issue(
215
+ file=file_str,
216
+ line=0,
217
+ category="no_reduced_motion",
218
+ snippet="(entire file)",
219
+ advice=(
220
+ "This file contains animations but no '@media (prefers-reduced-motion: reduce)' "
221
+ "block. Add one to disable or reduce motion for users who request it — "
222
+ "required for WCAG 2.1 AA compliance."
223
+ ),
224
+ ))
225
+
226
+ return issues
227
+
228
+
229
+ def print_issues(issues: list[Issue]) -> None:
230
+ for issue in issues:
231
+ loc = f"{issue.file}:{issue.line}" if issue.line else issue.file
232
+ category_label = CATEGORIES.get(issue.category, issue.category)
233
+ print(f"\n[{category_label}]")
234
+ print(f" Location : {loc}")
235
+ print(f" CSS : {issue.snippet}")
236
+ print(f" Fix : {issue.advice}")
237
+
238
+
239
+ def print_summary(issues: list[Issue]) -> None:
240
+ counts: dict[str, int] = defaultdict(int)
241
+ for issue in issues:
242
+ counts[issue.category] += 1
243
+ print("\n" + "=" * 60)
244
+ print("SUMMARY")
245
+ print("=" * 60)
246
+ if not counts:
247
+ print("No issues found.")
248
+ return
249
+ for cat, label in CATEGORIES.items():
250
+ count = counts.get(cat, 0)
251
+ if count:
252
+ print(f" {count:3d} {label}")
253
+ print(f" ---")
254
+ print(f" {sum(counts.values()):3d} Total issues")
255
+
256
+
257
+ def main() -> None:
258
+ parser = argparse.ArgumentParser(
259
+ description="Audit CSS/SCSS files for animation anti-patterns."
260
+ )
261
+ parser.add_argument(
262
+ "path",
263
+ help="A .css/.scss file or directory to scan recursively.",
264
+ )
265
+ args = parser.parse_args()
266
+
267
+ target = pathlib.Path(args.path)
268
+ if not target.exists():
269
+ print(f"ERROR: Path not found: {target}")
270
+ sys.exit(1)
271
+
272
+ files = find_css_files(target)
273
+ if not files:
274
+ print("No .css or .scss files found.")
275
+ sys.exit(0)
276
+
277
+ print(f"Scanning {len(files)} file(s) ...\n")
278
+
279
+ all_issues: list[Issue] = []
280
+ for f in files:
281
+ file_issues = audit_file(f)
282
+ all_issues.extend(file_issues)
283
+
284
+ if all_issues:
285
+ print_issues(all_issues)
286
+ else:
287
+ print("No animation anti-patterns detected.")
288
+
289
+ print_summary(all_issues)
290
+
291
+ sys.exit(1 if all_issues else 0)
292
+
293
+
294
+ if __name__ == "__main__":
295
+ main()
@@ -0,0 +1,129 @@
1
+ ---
2
+ name: booklib-mcp-guide
3
+ version: "1.0"
4
+ license: MIT
5
+ tags: [meta, mcp, tools, agent-guide]
6
+ description: "Use when working with BookLib MCP tools. Reference for lookup, review, remember, verify, guard — parameters, workflows, and anti-patterns."
7
+ ---
8
+
9
+ # BookLib MCP Tool Guide
10
+
11
+ BookLib exposes 5 MCP tools to AI coding agents. Each tool has a single purpose. This guide covers when to call each one, what parameters to pass, and common workflows.
12
+
13
+ ## Tool Reference
14
+
15
+ | Tool | When to call | Key params |
16
+ |------|-------------|------------|
17
+ | `lookup` | Before working with unfamiliar APIs or post-training deps | `query` (required), `file`, `limit`, `source` |
18
+ | `review` | User asks for deep code review of a specific file | `skill_name`, `file_path` (both required) |
19
+ | `remember` | User says "remember this", "capture", or makes a team decision | `title` (required), `content`, `type`, `tags` |
20
+ | `verify` | After writing code that uses unfamiliar or new APIs | `file_path` (required) |
21
+ | `guard` | After writing code that touches architecture or API choices | `file_path` (required) |
22
+
23
+ ## Decision Tree
24
+
25
+ ```
26
+ Need current docs for a post-training library -> lookup
27
+ Need a full expert review of a file -> review
28
+ User wants to save a decision or insight -> remember
29
+ Code uses unknown imports -> verify
30
+ Code might violate team rules -> guard
31
+ ```
32
+
33
+ ## Tool Details
34
+
35
+ ### lookup
36
+
37
+ Searches across post-training corrections, team knowledge, and expert skills. Returns structured principles with source citations.
38
+
39
+ Parameters:
40
+ - `query` (string, required): What you need to know. Include the library name and task.
41
+ - `file` (string): Path to the file being worked on. Adds language and component context.
42
+ - `limit` (number): Maximum results. Default: 3.
43
+ - `source` (enum: all/skills/knowledge): Filter by source type.
44
+
45
+ Prioritization order: (1) post-training gap corrections, (2) team knowledge nodes, (3) expert skill principles.
46
+
47
+ ### review
48
+
49
+ Audits a file against a named skill's principles. Returns structured findings with line references and citations.
50
+
51
+ Parameters:
52
+ - `skill_name` (string, required): The skill to review against (e.g., "effective-kotlin", "clean-code-reviewer").
53
+ - `file_path` (string, required): Path to the file to review.
54
+
55
+ ### remember
56
+
57
+ Creates a searchable knowledge node. Automatically indexed and auto-linked to related nodes.
58
+
59
+ Parameters:
60
+ - `title` (string, required): Short descriptive title.
61
+ - `content` (string): Detailed description in markdown.
62
+ - `type` (enum: insight/decision/pattern/note/research): Node type. Default: "insight".
63
+ - `tags` (string): Comma-separated tags.
64
+ - `links` (string): Link targets as "target:edge-type" pairs.
65
+
66
+ ### verify
67
+
68
+ Checks if a file's imports are covered by BookLib's index. Flags unknown post-training APIs that may need current docs.
69
+
70
+ Parameters:
71
+ - `file_path` (string, required): Path to the source file.
72
+
73
+ Returns: list of unknown imports with suggested documentation URLs.
74
+
75
+ ### guard
76
+
77
+ Checks if code contradicts captured team decisions. Compares code patterns against decision nodes.
78
+
79
+ Parameters:
80
+ - `file_path` (string, required): Path to the source file.
81
+
82
+ Returns: list of contradictions with the violated decision and source.
83
+
84
+ ## Common Workflows
85
+
86
+ ### 1. Gap detection and resolution
87
+
88
+ ```
89
+ verify file.ts -> finds unknown import "@stripe/stripe-js"
90
+ lookup "stripe js v5 api" -> returns current v5 docs
91
+ -> write correct code using current API
92
+ ```
93
+
94
+ ### 2. Team knowledge enforcement
95
+
96
+ ```
97
+ write code -> make architectural choice
98
+ guard file.ts -> flags: contradicts "use PaymentIntents not Charges"
99
+ -> fix the violation, commit
100
+ ```
101
+
102
+ ### 3. Knowledge capture during work
103
+
104
+ ```
105
+ discover a useful pattern -> remember "retry with exponential backoff" --type pattern
106
+ make a team decision -> remember "use PaymentIntents not Charges" --type decision
107
+ ```
108
+
109
+ ## Anti-Patterns
110
+
111
+ - **Don't call `lookup` for standard patterns.** React hooks, Python builtins, Go stdlib -- you already know these. Only call for project-specific or post-training knowledge.
112
+ - **Don't call `verify` on stdlib imports.** Standard library imports are always known. Only check third-party imports.
113
+ - **Don't call `remember` for ephemeral notes.** Only capture durable decisions, patterns, and insights that future sessions should know about.
114
+ - **Don't call `review` without a specific skill.** The skill_name parameter is required -- pick the most relevant one or use "clean-code-reviewer" as default.
115
+ - **Don't over-call tools.** One `lookup` per topic is enough. Don't repeat the same query hoping for different results.
116
+
117
+ ## CLI-Only Commands (Not MCP Tools)
118
+
119
+ These features are available via the `booklib` CLI but not exposed as MCP tools:
120
+
121
+ - `booklib connect <path>` -- connect a documentation source
122
+ - `booklib connect github releases <repo>` -- index GitHub changelogs
123
+ - `booklib connect notion database <id>` -- index Notion pages
124
+ - `booklib link <from> <to> --type <edge>` -- connect two knowledge nodes
125
+ - `booklib save-state --goal "..." --next "..."` -- save session for handoff
126
+ - `booklib nodes list` / `booklib nodes show <id>` -- list and inspect knowledge
127
+ - `booklib gaps` / `booklib resolve-gaps` -- detect and fix knowledge gaps
128
+ - `booklib analyze` -- show affected files and post-training APIs
129
+ - `booklib doctor` -- health check
@@ -0,0 +1,37 @@
1
+ {
2
+ "evals": [
3
+ {
4
+ "id": "eval-01-lookup-trigger",
5
+ "prompt": "You are editing frontend/src/lib/supabase.ts which imports @supabase/supabase-js.\nThe file currently has:\n\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!\nconst supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!\n\nexport const supabase = createClient(supabaseUrl, supabaseKey)\n\nYou need to add user authentication with email/password sign-in.\nBefore writing auth code, what BookLib tool should you call and why?",
6
+ "expectations": [
7
+ "Should call lookup with a query about supabase auth",
8
+ "Should NOT call lookup for standard TypeScript features",
9
+ "Should mention that supabase may be post-training",
10
+ "Should wait for lookup results before writing auth code",
11
+ "Should use the results to write correct v2 auth patterns"
12
+ ]
13
+ },
14
+ {
15
+ "id": "eval-02-guard-trigger",
16
+ "prompt": "You just wrote a payment processing module at src/payments/charge.ts:\n\nimport Stripe from 'stripe'\n\nconst stripe = new Stripe(process.env.STRIPE_SECRET_KEY!)\n\nexport async function processPayment(amount: number) {\n const charge = await stripe.charges.create({\n amount,\n currency: 'usd',\n source: 'tok_visa',\n })\n return charge\n}\n\nThe team previously decided to use PaymentIntents instead of Charges.\nWhat BookLib tool catches this violation and how does it work?",
17
+ "expectations": [
18
+ "Should mention the guard tool",
19
+ "Should explain guard checks code against team decisions",
20
+ "Should note the team decision about PaymentIntents",
21
+ "Should suggest fixing the code to use PaymentIntents",
22
+ "Should mention that guard runs automatically via PostToolUse hooks"
23
+ ]
24
+ },
25
+ {
26
+ "id": "eval-03-verify-trigger",
27
+ "prompt": "You added zod@3.25 to the project and wrote this validation module at src/lib/validate.ts:\n\nimport { z } from 'zod'\n\nexport const UserSchema = z.object({\n name: z.string().min(1),\n email: z.string().email(),\n age: z.number().int().positive(),\n role: z.enum(['admin', 'user', 'guest']),\n})\n\nexport type User = z.infer<typeof UserSchema>\n\nHow do you check if BookLib has documentation for this version of zod?\nWhat happens if zod@3.25 is a post-training library?",
28
+ "expectations": [
29
+ "Should mention the verify tool",
30
+ "Should explain verify checks if imports are in the BookLib index",
31
+ "Should note that zod@3.25 may be post-training",
32
+ "Should suggest running booklib verify on the file",
33
+ "Should mention that verify also runs automatically via hooks"
34
+ ]
35
+ }
36
+ ]
37
+ }
@@ -0,0 +1,34 @@
1
+ # After: Agent calls BookLib lookup before writing code
2
+
3
+ The agent calls lookup("supabase auth session") and gets the current v2.95 API.
4
+ It then writes code using the correct patterns.
5
+
6
+ ```typescript
7
+ import { createClient } from '@supabase/supabase-js'
8
+
9
+ const supabase = createClient(url, key, {
10
+ auth: {
11
+ autoRefreshToken: true,
12
+ persistSession: true,
13
+ },
14
+ })
15
+
16
+ // Correct: v2.95 session pattern
17
+ const { data: { session } } = await supabase.auth.getSession()
18
+
19
+ // Correct: v2 sign-in with password
20
+ const { data, error } = await supabase.auth.signInWithPassword({
21
+ email: 'user@example.com',
22
+ password: 'password123',
23
+ })
24
+
25
+ // Correct: v2 realtime channel pattern
26
+ const channel = supabase
27
+ .channel('messages')
28
+ .on('postgres_changes', { event: 'INSERT', schema: 'public' }, payload => {
29
+ console.log(payload)
30
+ })
31
+ .subscribe()
32
+ ```
33
+
34
+ The agent used current APIs because BookLib injected the correct knowledge.
@@ -0,0 +1,27 @@
1
+ # Before: Agent writes code without checking BookLib for post-training knowledge
2
+
3
+ The agent is asked to create a Supabase auth flow. Without calling the BookLib
4
+ lookup tool, it uses patterns from its training data which are outdated.
5
+
6
+ ```typescript
7
+ import { createClient } from '@supabase/supabase-js'
8
+
9
+ const supabase = createClient(url, key)
10
+
11
+ // Wrong: uses deprecated v1 auth pattern
12
+ const { data, error } = await supabase.auth.session()
13
+
14
+ // Wrong: old sign-in method
15
+ const { user, error: signInError } = await supabase.auth.signIn({
16
+ email: 'user@example.com',
17
+ password: 'password123',
18
+ })
19
+
20
+ // Wrong: old subscription pattern
21
+ const subscription = supabase
22
+ .from('messages')
23
+ .on('INSERT', payload => console.log(payload))
24
+ .subscribe()
25
+ ```
26
+
27
+ The code compiles but uses deprecated APIs that will fail at runtime.
@@ -0,0 +1,9 @@
1
+ # BookLib MCP Tool Catalog
2
+
3
+ | Tool | Purpose | Key Parameters |
4
+ |------|---------|---------------|
5
+ | lookup | Search for post-training docs, team decisions, expert knowledge | query, file, limit, source |
6
+ | review | Deep code review against a named skill | skill_name, file_path |
7
+ | remember | Capture a team decision or insight | title, type, tags |
8
+ | verify | Check if imports are covered by the index | file_path |
9
+ | guard | Check if code contradicts team decisions | file_path |