@booklib/core 2.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 (374) hide show
  1. package/.cursor/rules/booklib-standards.mdc +40 -0
  2. package/.gemini/context.md +372 -0
  3. package/AGENTS.md +166 -0
  4. package/CHANGELOG.md +226 -0
  5. package/CLAUDE.md +81 -0
  6. package/CODE_OF_CONDUCT.md +31 -0
  7. package/CONTRIBUTING.md +304 -0
  8. package/LICENSE +21 -0
  9. package/PLAN.md +28 -0
  10. package/README.ja.md +198 -0
  11. package/README.ko.md +198 -0
  12. package/README.md +503 -0
  13. package/README.pt-BR.md +198 -0
  14. package/README.uk.md +241 -0
  15. package/README.zh-CN.md +198 -0
  16. package/SECURITY.md +9 -0
  17. package/agents/architecture-reviewer.md +136 -0
  18. package/agents/booklib-reviewer.md +90 -0
  19. package/agents/data-reviewer.md +107 -0
  20. package/agents/jvm-reviewer.md +146 -0
  21. package/agents/python-reviewer.md +128 -0
  22. package/agents/rust-reviewer.md +115 -0
  23. package/agents/ts-reviewer.md +110 -0
  24. package/agents/ui-reviewer.md +117 -0
  25. package/assets/logo.svg +36 -0
  26. package/bin/booklib-mcp.js +304 -0
  27. package/bin/booklib.js +1705 -0
  28. package/bin/skills.cjs +1292 -0
  29. package/booklib-router.mdc +36 -0
  30. package/booklib.config.json +19 -0
  31. package/commands/animation-at-work.md +10 -0
  32. package/commands/clean-code-reviewer.md +10 -0
  33. package/commands/data-intensive-patterns.md +10 -0
  34. package/commands/data-pipelines.md +10 -0
  35. package/commands/design-patterns.md +10 -0
  36. package/commands/domain-driven-design.md +10 -0
  37. package/commands/effective-java.md +10 -0
  38. package/commands/effective-kotlin.md +10 -0
  39. package/commands/effective-python.md +10 -0
  40. package/commands/effective-typescript.md +10 -0
  41. package/commands/kotlin-in-action.md +10 -0
  42. package/commands/lean-startup.md +10 -0
  43. package/commands/microservices-patterns.md +10 -0
  44. package/commands/programming-with-rust.md +10 -0
  45. package/commands/refactoring-ui.md +10 -0
  46. package/commands/rust-in-action.md +10 -0
  47. package/commands/skill-router.md +10 -0
  48. package/commands/spring-boot-in-action.md +10 -0
  49. package/commands/storytelling-with-data.md +10 -0
  50. package/commands/system-design-interview.md +10 -0
  51. package/commands/using-asyncio-python.md +10 -0
  52. package/commands/web-scraping-python.md +10 -0
  53. package/community/registry.json +1616 -0
  54. package/hooks/hooks.json +23 -0
  55. package/hooks/posttooluse-capture.mjs +67 -0
  56. package/hooks/suggest.js +153 -0
  57. package/lib/agent-behaviors.js +40 -0
  58. package/lib/agent-detector.js +96 -0
  59. package/lib/config-loader.js +39 -0
  60. package/lib/conflict-resolver.js +148 -0
  61. package/lib/context-builder.js +574 -0
  62. package/lib/discovery-engine.js +298 -0
  63. package/lib/doctor/hook-installer.js +83 -0
  64. package/lib/doctor/usage-tracker.js +87 -0
  65. package/lib/engine/ai-features.js +253 -0
  66. package/lib/engine/auditor.js +103 -0
  67. package/lib/engine/bm25-index.js +178 -0
  68. package/lib/engine/capture.js +120 -0
  69. package/lib/engine/corrections.js +198 -0
  70. package/lib/engine/doctor.js +195 -0
  71. package/lib/engine/graph-injector.js +137 -0
  72. package/lib/engine/graph.js +161 -0
  73. package/lib/engine/handoff.js +405 -0
  74. package/lib/engine/indexer.js +242 -0
  75. package/lib/engine/parser.js +53 -0
  76. package/lib/engine/query-expander.js +42 -0
  77. package/lib/engine/reranker.js +40 -0
  78. package/lib/engine/rrf.js +59 -0
  79. package/lib/engine/scanner.js +151 -0
  80. package/lib/engine/searcher.js +139 -0
  81. package/lib/engine/session-coordinator.js +306 -0
  82. package/lib/engine/session-manager.js +429 -0
  83. package/lib/engine/synthesizer.js +70 -0
  84. package/lib/installer.js +70 -0
  85. package/lib/instinct-block.js +33 -0
  86. package/lib/mcp-config-writer.js +88 -0
  87. package/lib/paths.js +57 -0
  88. package/lib/profiles/design.md +19 -0
  89. package/lib/profiles/general.md +16 -0
  90. package/lib/profiles/research-analysis.md +22 -0
  91. package/lib/profiles/software-development.md +23 -0
  92. package/lib/profiles/writing-content.md +19 -0
  93. package/lib/project-initializer.js +916 -0
  94. package/lib/registry/skills.js +102 -0
  95. package/lib/registry-searcher.js +99 -0
  96. package/lib/rules/rules-manager.js +169 -0
  97. package/lib/skill-fetcher.js +333 -0
  98. package/lib/well-known-builder.js +70 -0
  99. package/lib/wizard/index.js +404 -0
  100. package/lib/wizard/integration-detector.js +41 -0
  101. package/lib/wizard/project-detector.js +100 -0
  102. package/lib/wizard/prompt.js +156 -0
  103. package/lib/wizard/registry-embeddings.js +107 -0
  104. package/lib/wizard/skill-recommender.js +69 -0
  105. package/llms-full.txt +254 -0
  106. package/llms.txt +70 -0
  107. package/package.json +45 -0
  108. package/research-reports/2026-04-01-current-architecture.md +160 -0
  109. package/research-reports/IDEAS.md +93 -0
  110. package/rules/common/clean-code.md +42 -0
  111. package/rules/java/effective-java.md +42 -0
  112. package/rules/kotlin/effective-kotlin.md +37 -0
  113. package/rules/python/effective-python.md +38 -0
  114. package/rules/rust/rust.md +37 -0
  115. package/rules/typescript/effective-typescript.md +42 -0
  116. package/scripts/gen-llms-full.mjs +36 -0
  117. package/scripts/gen-og.mjs +142 -0
  118. package/scripts/validate-frontmatter.js +25 -0
  119. package/skills/animation-at-work/SKILL.md +270 -0
  120. package/skills/animation-at-work/assets/example_asset.txt +1 -0
  121. package/skills/animation-at-work/evals/evals.json +44 -0
  122. package/skills/animation-at-work/evals/results.json +13 -0
  123. package/skills/animation-at-work/examples/after.md +64 -0
  124. package/skills/animation-at-work/examples/before.md +35 -0
  125. package/skills/animation-at-work/references/api_reference.md +369 -0
  126. package/skills/animation-at-work/references/review-checklist.md +79 -0
  127. package/skills/animation-at-work/scripts/audit_animations.py +295 -0
  128. package/skills/animation-at-work/scripts/example.py +1 -0
  129. package/skills/clean-code-reviewer/SKILL.md +444 -0
  130. package/skills/clean-code-reviewer/audit.json +35 -0
  131. package/skills/clean-code-reviewer/evals/evals.json +185 -0
  132. package/skills/clean-code-reviewer/evals/results.json +13 -0
  133. package/skills/clean-code-reviewer/examples/after.md +48 -0
  134. package/skills/clean-code-reviewer/examples/before.md +33 -0
  135. package/skills/clean-code-reviewer/references/api_reference.md +158 -0
  136. package/skills/clean-code-reviewer/references/practices-catalog.md +282 -0
  137. package/skills/clean-code-reviewer/references/review-checklist.md +254 -0
  138. package/skills/clean-code-reviewer/scripts/pre-review.py +206 -0
  139. package/skills/data-intensive-patterns/SKILL.md +267 -0
  140. package/skills/data-intensive-patterns/assets/example_asset.txt +1 -0
  141. package/skills/data-intensive-patterns/evals/evals.json +54 -0
  142. package/skills/data-intensive-patterns/evals/results.json +13 -0
  143. package/skills/data-intensive-patterns/examples/after.md +61 -0
  144. package/skills/data-intensive-patterns/examples/before.md +38 -0
  145. package/skills/data-intensive-patterns/references/api_reference.md +34 -0
  146. package/skills/data-intensive-patterns/references/patterns-catalog.md +551 -0
  147. package/skills/data-intensive-patterns/references/review-checklist.md +193 -0
  148. package/skills/data-intensive-patterns/scripts/adr.py +213 -0
  149. package/skills/data-intensive-patterns/scripts/example.py +1 -0
  150. package/skills/data-pipelines/SKILL.md +259 -0
  151. package/skills/data-pipelines/assets/example_asset.txt +1 -0
  152. package/skills/data-pipelines/evals/evals.json +45 -0
  153. package/skills/data-pipelines/evals/results.json +13 -0
  154. package/skills/data-pipelines/examples/after.md +97 -0
  155. package/skills/data-pipelines/examples/before.md +37 -0
  156. package/skills/data-pipelines/references/api_reference.md +301 -0
  157. package/skills/data-pipelines/references/review-checklist.md +181 -0
  158. package/skills/data-pipelines/scripts/example.py +1 -0
  159. package/skills/data-pipelines/scripts/new_pipeline.py +444 -0
  160. package/skills/design-patterns/SKILL.md +271 -0
  161. package/skills/design-patterns/assets/example_asset.txt +1 -0
  162. package/skills/design-patterns/evals/evals.json +46 -0
  163. package/skills/design-patterns/evals/results.json +13 -0
  164. package/skills/design-patterns/examples/after.md +52 -0
  165. package/skills/design-patterns/examples/before.md +29 -0
  166. package/skills/design-patterns/references/api_reference.md +1 -0
  167. package/skills/design-patterns/references/patterns-catalog.md +726 -0
  168. package/skills/design-patterns/references/review-checklist.md +173 -0
  169. package/skills/design-patterns/scripts/example.py +1 -0
  170. package/skills/design-patterns/scripts/scaffold.py +807 -0
  171. package/skills/domain-driven-design/SKILL.md +142 -0
  172. package/skills/domain-driven-design/assets/example_asset.txt +1 -0
  173. package/skills/domain-driven-design/evals/evals.json +48 -0
  174. package/skills/domain-driven-design/evals/results.json +13 -0
  175. package/skills/domain-driven-design/examples/after.md +80 -0
  176. package/skills/domain-driven-design/examples/before.md +43 -0
  177. package/skills/domain-driven-design/references/api_reference.md +1 -0
  178. package/skills/domain-driven-design/references/patterns-catalog.md +545 -0
  179. package/skills/domain-driven-design/references/review-checklist.md +158 -0
  180. package/skills/domain-driven-design/scripts/example.py +1 -0
  181. package/skills/domain-driven-design/scripts/scaffold.py +421 -0
  182. package/skills/effective-java/SKILL.md +227 -0
  183. package/skills/effective-java/assets/example_asset.txt +1 -0
  184. package/skills/effective-java/evals/evals.json +46 -0
  185. package/skills/effective-java/evals/results.json +13 -0
  186. package/skills/effective-java/examples/after.md +83 -0
  187. package/skills/effective-java/examples/before.md +37 -0
  188. package/skills/effective-java/references/api_reference.md +1 -0
  189. package/skills/effective-java/references/items-catalog.md +955 -0
  190. package/skills/effective-java/references/review-checklist.md +216 -0
  191. package/skills/effective-java/scripts/checkstyle_setup.py +211 -0
  192. package/skills/effective-java/scripts/example.py +1 -0
  193. package/skills/effective-kotlin/SKILL.md +271 -0
  194. package/skills/effective-kotlin/assets/example_asset.txt +1 -0
  195. package/skills/effective-kotlin/audit.json +29 -0
  196. package/skills/effective-kotlin/evals/evals.json +45 -0
  197. package/skills/effective-kotlin/evals/results.json +13 -0
  198. package/skills/effective-kotlin/examples/after.md +36 -0
  199. package/skills/effective-kotlin/examples/before.md +38 -0
  200. package/skills/effective-kotlin/references/api_reference.md +1 -0
  201. package/skills/effective-kotlin/references/practices-catalog.md +1228 -0
  202. package/skills/effective-kotlin/references/review-checklist.md +126 -0
  203. package/skills/effective-kotlin/scripts/example.py +1 -0
  204. package/skills/effective-python/SKILL.md +441 -0
  205. package/skills/effective-python/evals/evals.json +44 -0
  206. package/skills/effective-python/evals/results.json +13 -0
  207. package/skills/effective-python/examples/after.md +56 -0
  208. package/skills/effective-python/examples/before.md +40 -0
  209. package/skills/effective-python/ref-01-pythonic-thinking.md +202 -0
  210. package/skills/effective-python/ref-02-lists-and-dicts.md +146 -0
  211. package/skills/effective-python/ref-03-functions.md +186 -0
  212. package/skills/effective-python/ref-04-comprehensions-generators.md +211 -0
  213. package/skills/effective-python/ref-05-classes-interfaces.md +188 -0
  214. package/skills/effective-python/ref-06-metaclasses-attributes.md +209 -0
  215. package/skills/effective-python/ref-07-concurrency.md +213 -0
  216. package/skills/effective-python/ref-08-robustness-performance.md +248 -0
  217. package/skills/effective-python/ref-09-testing-debugging.md +253 -0
  218. package/skills/effective-python/ref-10-collaboration.md +175 -0
  219. package/skills/effective-python/references/api_reference.md +218 -0
  220. package/skills/effective-python/references/practices-catalog.md +483 -0
  221. package/skills/effective-python/references/review-checklist.md +190 -0
  222. package/skills/effective-python/scripts/lint.py +173 -0
  223. package/skills/effective-typescript/SKILL.md +262 -0
  224. package/skills/effective-typescript/audit.json +29 -0
  225. package/skills/effective-typescript/evals/evals.json +37 -0
  226. package/skills/effective-typescript/evals/results.json +13 -0
  227. package/skills/effective-typescript/examples/after.md +70 -0
  228. package/skills/effective-typescript/examples/before.md +47 -0
  229. package/skills/effective-typescript/references/api_reference.md +118 -0
  230. package/skills/effective-typescript/references/practices-catalog.md +371 -0
  231. package/skills/effective-typescript/scripts/review.py +169 -0
  232. package/skills/kotlin-in-action/SKILL.md +261 -0
  233. package/skills/kotlin-in-action/assets/example_asset.txt +1 -0
  234. package/skills/kotlin-in-action/evals/evals.json +43 -0
  235. package/skills/kotlin-in-action/evals/results.json +13 -0
  236. package/skills/kotlin-in-action/examples/after.md +53 -0
  237. package/skills/kotlin-in-action/examples/before.md +39 -0
  238. package/skills/kotlin-in-action/references/api_reference.md +1 -0
  239. package/skills/kotlin-in-action/references/practices-catalog.md +436 -0
  240. package/skills/kotlin-in-action/references/review-checklist.md +204 -0
  241. package/skills/kotlin-in-action/scripts/example.py +1 -0
  242. package/skills/kotlin-in-action/scripts/setup_detekt.py +224 -0
  243. package/skills/lean-startup/SKILL.md +160 -0
  244. package/skills/lean-startup/assets/example_asset.txt +1 -0
  245. package/skills/lean-startup/evals/evals.json +43 -0
  246. package/skills/lean-startup/evals/results.json +13 -0
  247. package/skills/lean-startup/examples/after.md +80 -0
  248. package/skills/lean-startup/examples/before.md +34 -0
  249. package/skills/lean-startup/references/api_reference.md +319 -0
  250. package/skills/lean-startup/references/review-checklist.md +137 -0
  251. package/skills/lean-startup/scripts/example.py +1 -0
  252. package/skills/lean-startup/scripts/new_experiment.py +286 -0
  253. package/skills/microservices-patterns/SKILL.md +384 -0
  254. package/skills/microservices-patterns/evals/evals.json +45 -0
  255. package/skills/microservices-patterns/evals/results.json +13 -0
  256. package/skills/microservices-patterns/examples/after.md +69 -0
  257. package/skills/microservices-patterns/examples/before.md +40 -0
  258. package/skills/microservices-patterns/references/patterns-catalog.md +391 -0
  259. package/skills/microservices-patterns/references/review-checklist.md +169 -0
  260. package/skills/microservices-patterns/scripts/new_service.py +583 -0
  261. package/skills/programming-with-rust/SKILL.md +209 -0
  262. package/skills/programming-with-rust/evals/evals.json +37 -0
  263. package/skills/programming-with-rust/evals/results.json +13 -0
  264. package/skills/programming-with-rust/examples/after.md +107 -0
  265. package/skills/programming-with-rust/examples/before.md +59 -0
  266. package/skills/programming-with-rust/references/api_reference.md +152 -0
  267. package/skills/programming-with-rust/references/practices-catalog.md +335 -0
  268. package/skills/programming-with-rust/scripts/review.py +142 -0
  269. package/skills/refactoring-ui/SKILL.md +362 -0
  270. package/skills/refactoring-ui/assets/example_asset.txt +1 -0
  271. package/skills/refactoring-ui/evals/evals.json +45 -0
  272. package/skills/refactoring-ui/evals/results.json +13 -0
  273. package/skills/refactoring-ui/examples/after.md +85 -0
  274. package/skills/refactoring-ui/examples/before.md +58 -0
  275. package/skills/refactoring-ui/references/api_reference.md +355 -0
  276. package/skills/refactoring-ui/references/review-checklist.md +114 -0
  277. package/skills/refactoring-ui/scripts/audit_css.py +250 -0
  278. package/skills/refactoring-ui/scripts/example.py +1 -0
  279. package/skills/rust-in-action/SKILL.md +350 -0
  280. package/skills/rust-in-action/evals/evals.json +38 -0
  281. package/skills/rust-in-action/evals/results.json +13 -0
  282. package/skills/rust-in-action/examples/after.md +156 -0
  283. package/skills/rust-in-action/examples/before.md +56 -0
  284. package/skills/rust-in-action/references/practices-catalog.md +346 -0
  285. package/skills/rust-in-action/scripts/review.py +147 -0
  286. package/skills/skill-router/SKILL.md +186 -0
  287. package/skills/skill-router/evals/evals.json +38 -0
  288. package/skills/skill-router/evals/results.json +13 -0
  289. package/skills/skill-router/examples/after.md +63 -0
  290. package/skills/skill-router/examples/before.md +39 -0
  291. package/skills/skill-router/references/api_reference.md +24 -0
  292. package/skills/skill-router/references/routing-heuristics.md +89 -0
  293. package/skills/skill-router/references/skill-catalog.md +174 -0
  294. package/skills/skill-router/scripts/route.py +266 -0
  295. package/skills/spring-boot-in-action/SKILL.md +340 -0
  296. package/skills/spring-boot-in-action/evals/evals.json +39 -0
  297. package/skills/spring-boot-in-action/evals/results.json +13 -0
  298. package/skills/spring-boot-in-action/examples/after.md +185 -0
  299. package/skills/spring-boot-in-action/examples/before.md +84 -0
  300. package/skills/spring-boot-in-action/references/practices-catalog.md +403 -0
  301. package/skills/spring-boot-in-action/scripts/review.py +184 -0
  302. package/skills/storytelling-with-data/SKILL.md +241 -0
  303. package/skills/storytelling-with-data/assets/example_asset.txt +1 -0
  304. package/skills/storytelling-with-data/evals/evals.json +47 -0
  305. package/skills/storytelling-with-data/evals/results.json +13 -0
  306. package/skills/storytelling-with-data/examples/after.md +50 -0
  307. package/skills/storytelling-with-data/examples/before.md +33 -0
  308. package/skills/storytelling-with-data/references/api_reference.md +379 -0
  309. package/skills/storytelling-with-data/references/review-checklist.md +111 -0
  310. package/skills/storytelling-with-data/scripts/chart_review.py +301 -0
  311. package/skills/storytelling-with-data/scripts/example.py +1 -0
  312. package/skills/system-design-interview/SKILL.md +233 -0
  313. package/skills/system-design-interview/assets/example_asset.txt +1 -0
  314. package/skills/system-design-interview/evals/evals.json +46 -0
  315. package/skills/system-design-interview/evals/results.json +13 -0
  316. package/skills/system-design-interview/examples/after.md +94 -0
  317. package/skills/system-design-interview/examples/before.md +27 -0
  318. package/skills/system-design-interview/references/api_reference.md +582 -0
  319. package/skills/system-design-interview/references/review-checklist.md +201 -0
  320. package/skills/system-design-interview/scripts/example.py +1 -0
  321. package/skills/system-design-interview/scripts/new_design.py +421 -0
  322. package/skills/using-asyncio-python/SKILL.md +290 -0
  323. package/skills/using-asyncio-python/assets/example_asset.txt +1 -0
  324. package/skills/using-asyncio-python/evals/evals.json +43 -0
  325. package/skills/using-asyncio-python/evals/results.json +13 -0
  326. package/skills/using-asyncio-python/examples/after.md +68 -0
  327. package/skills/using-asyncio-python/examples/before.md +39 -0
  328. package/skills/using-asyncio-python/references/api_reference.md +267 -0
  329. package/skills/using-asyncio-python/references/review-checklist.md +149 -0
  330. package/skills/using-asyncio-python/scripts/check_blocking.py +270 -0
  331. package/skills/using-asyncio-python/scripts/example.py +1 -0
  332. package/skills/web-scraping-python/SKILL.md +280 -0
  333. package/skills/web-scraping-python/assets/example_asset.txt +1 -0
  334. package/skills/web-scraping-python/evals/evals.json +46 -0
  335. package/skills/web-scraping-python/evals/results.json +13 -0
  336. package/skills/web-scraping-python/examples/after.md +109 -0
  337. package/skills/web-scraping-python/examples/before.md +40 -0
  338. package/skills/web-scraping-python/references/api_reference.md +393 -0
  339. package/skills/web-scraping-python/references/review-checklist.md +163 -0
  340. package/skills/web-scraping-python/scripts/example.py +1 -0
  341. package/skills/web-scraping-python/scripts/new_scraper.py +231 -0
  342. package/skills/writing-plans/audit.json +34 -0
  343. package/tests/agent-detector.test.js +83 -0
  344. package/tests/corrections.test.js +245 -0
  345. package/tests/doctor/hook-installer.test.js +72 -0
  346. package/tests/doctor/usage-tracker.test.js +140 -0
  347. package/tests/engine/benchmark-eval.test.js +31 -0
  348. package/tests/engine/bm25-index.test.js +85 -0
  349. package/tests/engine/capture-command.test.js +35 -0
  350. package/tests/engine/capture.test.js +17 -0
  351. package/tests/engine/graph-augmented-search.test.js +107 -0
  352. package/tests/engine/graph-injector.test.js +44 -0
  353. package/tests/engine/graph.test.js +216 -0
  354. package/tests/engine/hybrid-searcher.test.js +74 -0
  355. package/tests/engine/indexer-bm25.test.js +37 -0
  356. package/tests/engine/mcp-tools.test.js +73 -0
  357. package/tests/engine/project-initializer-mcp.test.js +99 -0
  358. package/tests/engine/query-expander.test.js +36 -0
  359. package/tests/engine/reranker.test.js +51 -0
  360. package/tests/engine/rrf.test.js +49 -0
  361. package/tests/engine/srag-prefix.test.js +47 -0
  362. package/tests/instinct-block.test.js +23 -0
  363. package/tests/mcp-config-writer.test.js +60 -0
  364. package/tests/project-initializer-new-agents.test.js +48 -0
  365. package/tests/rules/rules-manager.test.js +230 -0
  366. package/tests/well-known-builder.test.js +40 -0
  367. package/tests/wizard/integration-detector.test.js +31 -0
  368. package/tests/wizard/project-detector.test.js +51 -0
  369. package/tests/wizard/prompt-session.test.js +61 -0
  370. package/tests/wizard/prompt.test.js +16 -0
  371. package/tests/wizard/registry-embeddings.test.js +35 -0
  372. package/tests/wizard/skill-recommender.test.js +34 -0
  373. package/tests/wizard/slot-count.test.js +25 -0
  374. package/vercel.json +21 -0
@@ -0,0 +1,36 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import matter from 'gray-matter';
4
+
5
+ const skillsRoot = './skills';
6
+ const outputFile = './llms-full.txt';
7
+
8
+ async function generateFullLLM() {
9
+ const skills = fs.readdirSync(skillsRoot)
10
+ .filter(name => fs.statSync(path.join(skillsRoot, name)).isDirectory() && fs.existsSync(path.join(skillsRoot, name, 'SKILL.md')));
11
+
12
+ let output = '# BookLib Full Skill Catalog\n\nThis file contains detailed descriptions and triggers for every skill in the BookLib library, optimized for RAG retrieval.\n\n';
13
+
14
+ for (const skill of skills) {
15
+ const skillPath = path.join(skillsRoot, skill, 'SKILL.md');
16
+ const content = fs.readFileSync(skillPath, 'utf8');
17
+ const { data: frontmatter } = matter(content);
18
+
19
+ output += `## Skill: ${frontmatter.name || skill}\n`;
20
+ output += `**Description**: ${frontmatter.description || 'No description available.'}\n`;
21
+ output += `**Directory**: \`skills/${skill}/\`\n`;
22
+
23
+ // Extract triggers if available in frontmatter or first paragraph
24
+ const triggerMatch = content.match(/Trigger on (.*)\./);
25
+ if (triggerMatch) {
26
+ output += `**Triggers**: ${triggerMatch[1]}\n`;
27
+ }
28
+
29
+ output += '\n---\n\n';
30
+ }
31
+
32
+ fs.writeFileSync(outputFile, output.trim());
33
+ console.log(`Generated ${outputFile} with ${skills.length} skills.`);
34
+ }
35
+
36
+ generateFullLLM().catch(console.error);
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * gen-og.mjs — generates docs/og.png (1200×630) for GitHub Pages OG preview.
4
+ * Usage: node scripts/gen-og.mjs
5
+ * Requires: npm install -g puppeteer OR npx puppeteer is available
6
+ */
7
+ import { writeFileSync, mkdirSync } from "fs";
8
+ import { join, dirname } from "path";
9
+ import { fileURLToPath } from "url";
10
+
11
+ const __dirname = dirname(fileURLToPath(import.meta.url));
12
+ const OUT = join(__dirname, "../docs/og.png");
13
+
14
+ const HTML = `<!DOCTYPE html>
15
+ <html>
16
+ <head>
17
+ <meta charset="UTF-8"/>
18
+ <style>
19
+ * { margin: 0; padding: 0; box-sizing: border-box; }
20
+ body {
21
+ width: 1200px; height: 630px; overflow: hidden;
22
+ background: #0d0d1a;
23
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
24
+ display: flex;
25
+ align-items: center;
26
+ justify-content: space-between;
27
+ padding: 0 80px;
28
+ position: relative;
29
+ }
30
+
31
+ /* Left: text content */
32
+ .left { flex: 0 0 auto; max-width: 540px; z-index: 2; }
33
+
34
+ .org {
35
+ font-size: 22px; font-weight: 500; color: #6366f1;
36
+ letter-spacing: 0.04em; margin-bottom: 16px;
37
+ font-family: "SF Mono", "Fira Code", monospace;
38
+ }
39
+ h1 {
40
+ font-size: 72px; font-weight: 800; color: #f1f5f9;
41
+ line-height: 1; letter-spacing: -0.04em; margin-bottom: 20px;
42
+ }
43
+ .tagline {
44
+ font-size: 24px; color: #64748b; line-height: 1.4; margin-bottom: 40px;
45
+ max-width: 460px;
46
+ }
47
+ .pills { display: flex; gap: 12px; flex-wrap: wrap; }
48
+ .pill {
49
+ background: #161625; border: 1px solid #2d2d4a;
50
+ border-radius: 999px; padding: 8px 20px;
51
+ font-size: 15px; color: #a5b4fc; font-weight: 600;
52
+ }
53
+
54
+ /* Right: book grid */
55
+ .books {
56
+ display: grid;
57
+ grid-template-columns: repeat(5, 1fr);
58
+ gap: 8px;
59
+ width: 420px;
60
+ flex-shrink: 0;
61
+ opacity: 0.92;
62
+ }
63
+ .book {
64
+ aspect-ratio: 2/3;
65
+ border-radius: 5px;
66
+ background: var(--c);
67
+ position: relative;
68
+ overflow: hidden;
69
+ }
70
+ .book::after {
71
+ content: "";
72
+ position: absolute; inset: 0;
73
+ background: linear-gradient(135deg, rgba(255,255,255,0.08) 0%, transparent 60%);
74
+ }
75
+ /* Spine line */
76
+ .book::before {
77
+ content: "";
78
+ position: absolute; top: 0; bottom: 0; left: 8px;
79
+ width: 2px; background: rgba(0,0,0,0.2);
80
+ }
81
+
82
+ /* Fade edge on left side of book grid */
83
+ .books-wrap {
84
+ position: relative;
85
+ flex-shrink: 0;
86
+ }
87
+ .books-wrap::before {
88
+ content: "";
89
+ position: absolute; top: 0; bottom: 0; left: -60px;
90
+ width: 80px;
91
+ background: linear-gradient(to right, #0d0d1a, transparent);
92
+ z-index: 1;
93
+ pointer-events: none;
94
+ }
95
+ </style>
96
+ </head>
97
+ <body>
98
+ <div class="left">
99
+ <div class="org">booklib-ai / skills</div>
100
+ <h1>Skills</h1>
101
+ <p class="tagline">Expert knowledge from 22 canonical programming books — packaged as AI agent skills.</p>
102
+ <div class="pills">
103
+ <span class="pill">22 skills</span>
104
+ <span class="pill">Claude Code</span>
105
+ <span class="pill">Cursor</span>
106
+ <span class="pill">Copilot</span>
107
+ </div>
108
+ </div>
109
+
110
+ <div class="books-wrap">
111
+ <div class="books">
112
+ ${[
113
+ "#1e3a5f","#5f1e1e","#1e5f2a","#5f4a1e","#2a1e5f",
114
+ "#1e4d5f","#5f1e4a","#3d5f1e","#5f3d1e","#1e5f5f",
115
+ "#4a1e5f","#1e5f3d","#5f5f1e","#1e2a5f","#5f1e2a",
116
+ "#2a5f1e","#5f2a1e","#1e5f4a","#4a5f1e","#1e4a5f",
117
+ "#5f1e5f","#3d1e5f","#1e5f1e","#5f3d3d","#1e3d5f",
118
+ "#5f4d1e","#1e4d3d","#4d1e1e","#1e1e4d","#3d5f3d",
119
+ ].map(c => `<div class="book" style="--c:${c}"></div>`).join("")}
120
+ </div>
121
+ </div>
122
+ </body>
123
+ </html>`;
124
+
125
+ let puppeteer;
126
+ try {
127
+ puppeteer = await import("puppeteer");
128
+ } catch {
129
+ // Try puppeteer-core as fallback
130
+ puppeteer = await import("puppeteer-core");
131
+ }
132
+
133
+ const browser = await puppeteer.default.launch({ headless: true });
134
+ const page = await browser.newPage();
135
+ await page.setViewport({ width: 1200, height: 630, deviceScaleFactor: 2 });
136
+ await page.setContent(HTML, { waitUntil: "networkidle0" });
137
+ const buf = await page.screenshot({ type: "png" });
138
+ await browser.close();
139
+
140
+ mkdirSync(dirname(OUT), { recursive: true });
141
+ writeFileSync(OUT, buf);
142
+ console.log(`Written: ${OUT} (${(buf.length / 1024).toFixed(0)} KB)`);
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import matter from 'gray-matter';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const SKILLS_DIR = path.resolve(fileURLToPath(import.meta.url), '../../skills');
8
+ const REQUIRED = ['name', 'description', 'version', 'tags', 'license'];
9
+
10
+ let failures = 0;
11
+ for (const skill of fs.readdirSync(SKILLS_DIR)) {
12
+ const file = path.join(SKILLS_DIR, skill, 'SKILL.md');
13
+ if (!fs.existsSync(file)) continue;
14
+ const { data } = matter(fs.readFileSync(file, 'utf8'));
15
+ const missing = REQUIRED.filter(field => {
16
+ const v = data[field];
17
+ return v === undefined || v === null || v === '' || (Array.isArray(v) && v.length === 0);
18
+ });
19
+ if (missing.length) {
20
+ console.log(`MISSING in ${skill}: ${missing.join(', ')}`);
21
+ failures++;
22
+ }
23
+ }
24
+ if (failures === 0) console.log('All skills compliant.');
25
+ process.exit(failures > 0 ? 1 : 0);
@@ -0,0 +1,270 @@
1
+ ---
2
+ name: animation-at-work
3
+ version: "1.0"
4
+ license: MIT
5
+ tags: [design, animation, ui]
6
+ description: >
7
+ Apply web animation principles from Animation at Work by Rachel Nabors.
8
+ Covers human perception of motion, 12 principles of animation, animation
9
+ patterns (transitions, supplements, feedback, demonstrations, decorations),
10
+ CSS transitions, CSS animations, Web Animations API, SVG/Canvas/WebGL,
11
+ communicating animation with storyboards and motion comps, performance
12
+ (composite-only properties, will-change, RAIL), accessibility (prefers-
13
+ reduced-motion, vestibular disorders), and team workflow. Trigger on
14
+ "animation", "transition", "CSS animation", "keyframe", "easing",
15
+ "motion design", "web animation", "prefers-reduced-motion", "storyboard",
16
+ "parallax", "loading animation", "hover effect", "micro-interaction".
17
+ ---
18
+
19
+ # Animation at Work Skill
20
+
21
+ You are an expert web animation advisor grounded in the 5 chapters from
22
+ *Animation at Work* by Rachel Nabors. You help in two modes:
23
+
24
+ 1. **Design Application** — Apply animation principles to create purposeful, performant web animations
25
+ 2. **Design Review** — Analyze existing animations and recommend improvements
26
+
27
+ ## How to Decide Which Mode
28
+
29
+ - If the user asks to *create*, *add*, *implement*, *animate*, or *build* animations → **Design Application**
30
+ - If the user asks to *review*, *audit*, *evaluate*, *optimize*, or *fix* animations → **Design Review**
31
+ - If ambiguous, ask briefly which mode they'd prefer
32
+
33
+ ---
34
+
35
+ ## Mode 1: Design Application
36
+
37
+ When helping create animations, follow this decision flow:
38
+
39
+ ### Step 1 — Classify the Animation's Purpose
40
+
41
+ Every animation must have a clear purpose. Classify using these five patterns:
42
+
43
+ | Pattern | Purpose | When to Use | Example |
44
+ |---------|---------|-------------|---------|
45
+ | **Transition** | Show state change between views/states | Navigating pages, opening panels, switching tabs | Page slide-in, modal open/close |
46
+ | **Supplement** | Bring elements into/out of a view that's already in place | Adding items to lists, showing notifications, revealing content | Toast notification slide-in, list item appear |
47
+ | **Feedback** | Confirm a user action was received | Button press, form submit, toggle | Button press ripple, checkbox animation |
48
+ | **Demonstration** | Explain how something works or draw attention | Onboarding, tutorials, feature discovery | Animated walkthrough, pulsing CTA |
49
+ | **Decoration** | Ambient, non-functional delight | Background effects, idle states | Parallax background, floating particles |
50
+
51
+ **Key principle**: If an animation doesn't fit any of these patterns, question whether it's needed. Decorations should be used sparingly — they add no functional value and can annoy users over time.
52
+
53
+ ### Step 2 — Choose the Right Technology
54
+
55
+ Read `references/api_reference.md` for detailed API specifics. Quick decision guide:
56
+
57
+ | Need | Technology | Why |
58
+ |------|-----------|-----|
59
+ | Simple hover/focus effects | CSS Transitions | Declarative, performant, minimal code |
60
+ | Looping or multi-step animations | CSS Animations (@keyframes) | Built-in iteration, keyframe control |
61
+ | Playback control (play/pause/reverse/scrub) | Web Animations API | JavaScript control with CSS performance |
62
+ | Complex coordinated sequences | Web Animations API | Timeline coordination, promises, grouping |
63
+ | Character animation or complex graphics | SVG + SMIL or Canvas | Vector scalability, per-element control |
64
+ | 3D or particle effects | WebGL/Three.js | GPU-accelerated 3D rendering |
65
+ | Simple loading indicators | CSS Animations | Self-contained, no JS needed |
66
+
67
+ ### Step 3 — Apply Motion Design Principles
68
+
69
+ **The 12 Principles of Animation** (from Disney, adapted for UI):
70
+
71
+ The most relevant for web UI:
72
+
73
+ - **Timing and spacing** — Duration and easing control perceived weight and personality. Fast (100–200ms) for feedback, medium (200–500ms) for transitions, slow (500ms+) for demonstrations
74
+ - **Anticipation** — Brief preparatory motion before the main action (button slight shrink before expanding)
75
+ - **Follow-through and overlapping action** — Elements don't all stop at once; stagger them for natural feel
76
+ - **Staging** — Direct user attention to what matters; animate the focal point, keep surroundings still
77
+ - **Ease in / ease out (slow in, slow out)** — Objects accelerate and decelerate naturally; avoid linear easing for UI
78
+ - **Arcs** — Natural motion follows curved paths, not straight lines
79
+ - **Secondary action** — Supporting animations that reinforce the main action without distracting
80
+ - **Exaggeration** — Amplify motion slightly for clarity (a bounce overshoot on a panel opening)
81
+ - **Appeal** — The animation should feel pleasant and appropriate for the brand
82
+
83
+ **Easing guidance**:
84
+ - `ease-out` — Best for elements **entering** (fast start, gentle stop)
85
+ - `ease-in` — Best for elements **leaving** (gentle start, fast exit)
86
+ - `ease-in-out` — Best for elements that **stay on screen** and move position
87
+ - `linear` — Only for continuous motion (progress bars, spinning loaders)
88
+ - Custom `cubic-bezier()` — For brand-specific personality
89
+
90
+ **Duration guidance**:
91
+ - Micro-interactions (feedback): 100–200ms
92
+ - Transitions between states: 200–500ms
93
+ - Complex demonstrations: 500ms–1s
94
+ - Page transitions: 300–500ms
95
+ - Never exceed 1s for functional animations (users feel delay)
96
+
97
+ ### Step 4 — Build with Performance in Mind
98
+
99
+ **Composite-only properties** (GPU-accelerated, no layout/paint):
100
+ - `transform` (translate, scale, rotate)
101
+ - `opacity`
102
+
103
+ **Avoid animating**: `width`, `height`, `top`, `left`, `margin`, `padding`, `border`, `font-size` — these trigger layout recalculation.
104
+
105
+ **Performance tips**:
106
+ - Use `will-change` to hint browser about upcoming animations (but sparingly — overuse wastes memory)
107
+ - Promote elements to their own compositor layer for complex animations
108
+ - Use `requestAnimationFrame` for JS-driven animations
109
+ - Test on low-powered devices, not just your dev machine
110
+ - Follow the RAIL model: Response <100ms, Animation <16ms/frame, Idle <50ms, Load <1000ms
111
+
112
+ ### Step 5 — Handle Accessibility
113
+
114
+ **Always implement `prefers-reduced-motion`**:
115
+ ```css
116
+ @media (prefers-reduced-motion: reduce) {
117
+ *, *::before, *::after {
118
+ animation-duration: 0.01ms !important;
119
+ animation-iteration-count: 1 !important;
120
+ transition-duration: 0.01ms !important;
121
+ }
122
+ }
123
+ ```
124
+
125
+ **Vestibular disorder considerations**:
126
+ - Parallax scrolling can cause dizziness — provide alternative
127
+ - Large-scale motion across the screen is more triggering than small, contained animations
128
+ - Zooming/scaling effects are problematic
129
+ - Auto-playing animations should be pausable
130
+ - Flashing content (>3 times/sec) can trigger seizures — never do this
131
+
132
+ **Safe alternatives when motion is reduced**:
133
+ - Cross-fade (opacity) instead of sliding
134
+ - Instant state change instead of animated transition
135
+ - Static illustrations instead of animated demonstrations
136
+
137
+ ### Design Application Examples
138
+
139
+ **Example 1 — Toast Notification (Supplement):**
140
+ ```css
141
+ .toast {
142
+ transform: translateY(100%);
143
+ opacity: 0;
144
+ transition: transform 300ms ease-out, opacity 300ms ease-out;
145
+ }
146
+ .toast.visible {
147
+ transform: translateY(0);
148
+ opacity: 1;
149
+ }
150
+ @media (prefers-reduced-motion: reduce) {
151
+ .toast { transition-duration: 0.01ms !important; }
152
+ }
153
+ ```
154
+
155
+ **Example 2 — Button Feedback:**
156
+ ```css
157
+ .btn:active {
158
+ transform: scale(0.95);
159
+ transition: transform 100ms ease-in;
160
+ }
161
+ ```
162
+
163
+ **Example 3 — Page Transition (Web Animations API):**
164
+ ```js
165
+ const outgoing = currentPage.animate(
166
+ [{ opacity: 1, transform: 'translateX(0)' },
167
+ { opacity: 0, transform: 'translateX(-20px)' }],
168
+ { duration: 250, easing: 'ease-in', fill: 'forwards' }
169
+ );
170
+ outgoing.finished.then(() => {
171
+ nextPage.animate(
172
+ [{ opacity: 0, transform: 'translateX(20px)' },
173
+ { opacity: 1, transform: 'translateX(0)' }],
174
+ { duration: 250, easing: 'ease-out', fill: 'forwards' }
175
+ );
176
+ });
177
+ ```
178
+
179
+ ---
180
+
181
+ ## Mode 2: Design Review
182
+
183
+ When reviewing animations, read `references/review-checklist.md` for the full checklist.
184
+
185
+ ### Review Process
186
+
187
+ 1. **Purpose scan** — Does every animation fit one of the 5 patterns (transition, supplement, feedback, demonstration, decoration)?
188
+ 2. **Performance scan** — Are only composite properties animated? Any layout thrashing?
189
+ 3. **Accessibility scan** — Is `prefers-reduced-motion` implemented? Any vestibular triggers?
190
+ 4. **Timing scan** — Are durations appropriate? Any animation exceeding 1s for functional use?
191
+ 5. **Easing scan** — Are easings appropriate for the direction of motion?
192
+ 6. **Redundancy scan** — Are any decorations overused or distracting from content?
193
+
194
+ ### Review Output Format
195
+
196
+ ```
197
+ ## Summary
198
+ One paragraph: overall animation quality, main strengths, key concerns.
199
+
200
+ ## Purpose Issues
201
+ - **Animation**: which element/interaction
202
+ - **Problem**: missing purpose, wrong pattern, excessive decoration
203
+ - **Fix**: recommended change with pattern reference
204
+
205
+ ## Performance Issues
206
+ - **Animation**: which element/property
207
+ - **Problem**: layout-triggering property, missing will-change, jank
208
+ - **Fix**: switch to composite-only property, optimize
209
+
210
+ ## Accessibility Issues
211
+ - **Animation**: which element
212
+ - **Problem**: missing reduced-motion, vestibular trigger, no pause control
213
+ - **Fix**: add media query, provide alternative
214
+
215
+ ## Timing/Easing Issues
216
+ - **Animation**: which element
217
+ - **Problem**: too slow, wrong easing, linear on UI element
218
+ - **Fix**: recommended duration and easing
219
+
220
+ ## Recommendations
221
+ Priority-ordered list with specific chapter references.
222
+ ```
223
+
224
+ ### Common Animation Anti-Patterns to Flag
225
+
226
+ - **Animation for animation's sake** → Ch 2: Every animation needs a purpose from the 5 patterns
227
+ - **Linear easing on UI elements** → Ch 1: Real objects ease in/out; linear feels robotic
228
+ - **Animating layout properties** → Ch 3: Use transform/opacity only for performance
229
+ - **No reduced-motion support** → Ch 5: Always implement prefers-reduced-motion
230
+ - **Too-long duration** → Ch 1: Functional animations should be under 1s
231
+ - **Auto-playing without pause** → Ch 5: Users must be able to stop animations
232
+ - **Excessive decorations** → Ch 2: Decorations have diminishing returns and can annoy
233
+ - **Same easing for enter and exit** → Ch 1: Use ease-out for enter, ease-in for exit
234
+ - **Parallax without fallback** → Ch 5: Parallax triggers vestibular issues
235
+ - **Flash rate >3/sec** → Ch 5: Can trigger seizures; never exceed this
236
+ - **`display: none` ↔ `display: block` transitions** → Ch 3: `display` is not an animatable property; switching between `none` and `block` causes an instant jump — the animation runs but the element appears/disappears immediately. Fix: use `opacity`/`transform` combined with `visibility: hidden` or `pointer-events: none` to keep the element in the flow while visually hidden, or use the modern `@starting-style` rule.
237
+
238
+ ### Praiseworthy Patterns to Recognize
239
+
240
+ When code already does these well, **explicitly acknowledge them** in your review:
241
+
242
+ - **Composite-only animation** — Animating only `transform` and `opacity` (GPU-accelerated, no layout/paint)
243
+ - **Correct easing directionality** — `ease-out` for entering elements, `ease-in` for exiting elements
244
+ - **Consistent duration hierarchy** — Durations ordered by interaction weight: 100ms (press feedback) → 200ms (hover/small UI) → 300ms (notifications) → 400ms (reveals) — shows intentional design
245
+ - **`prefers-reduced-motion` implementation** — Especially the global `*, *::before, *::after` block that sets `animation-duration: 0.01ms` and `transition-duration: 0.01ms` — this is the correct canonical approach
246
+ - **`pointer-events: none` on hidden elements** — Prevents interaction with invisible elements without removing from DOM; cleaner than `display: none` toggling
247
+ - **WAAPI with IntersectionObserver** — Using `element.animate()` inside an IntersectionObserver callback avoids scroll-event jank; calling `observer.unobserve()` after triggering prevents repeat-fire — both are signs of mature implementation
248
+
249
+ ### Calibrating Review Severity
250
+
251
+ **Not every review needs problems.** When code is well-designed:
252
+
253
+ 1. Lead with genuine praise for what's done correctly — be specific about which patterns are good and why
254
+ 2. If you suggest improvements, frame them explicitly as "minor optional improvements" or "polish ideas" — do not label them 🔴 Critical or High unless they are genuine accessibility or performance regressions
255
+ 3. Do not manufacture issues to appear thorough; a short, positive review of good code is more valuable than a padded list of nitpicks
256
+ 4. The summary paragraph should reflect the overall quality honestly — if it's well-crafted, say so directly
257
+
258
+ ---
259
+
260
+ ## General Guidelines
261
+
262
+ - **Purpose first** — Every animation must serve a functional purpose or be consciously decorative
263
+ - **Performance is non-negotiable** — Only animate composite properties (transform, opacity)
264
+ - **Accessibility is mandatory** — Always implement prefers-reduced-motion
265
+ - **Duration matters** — Fast for feedback (100–200ms), medium for transitions (200–500ms), slow for demos (500ms+)
266
+ - **Easing conveys personality** — ease-out for entering, ease-in for leaving, ease-in-out for repositioning
267
+ - **Less is more** — One well-crafted animation beats ten flashy ones
268
+ - **Test on real devices** — Animations that work on your MacBook may jank on budget phones
269
+ - For detailed API reference, read `references/api_reference.md`
270
+ - For review checklists, read `references/review-checklist.md`
@@ -0,0 +1,44 @@
1
+ {
2
+ "evals": [
3
+ {
4
+ "id": "eval-01-no-easing-layout-properties-inconsistent-duration",
5
+ "prompt": "Review these CSS animations:\n\n```css\n/* Modal open animation */\n.modal {\n display: none;\n width: 600px;\n padding: 40px;\n background: white;\n border-radius: 8px;\n position: fixed;\n top: 50%;\n left: 50%;\n margin-top: -200px;\n margin-left: -300px;\n}\n\n.modal.visible {\n display: block;\n animation: modal-open 0.4s linear;\n}\n\n@keyframes modal-open {\n from {\n margin-top: -400px;\n opacity: 0;\n width: 400px;\n }\n to {\n margin-top: -200px;\n opacity: 1;\n width: 600px;\n }\n}\n\n/* Button hover */\n.btn:hover {\n background-color: #0056b3;\n padding: 14px 28px;\n border-radius: 12px;\n transition: all 2s linear;\n}\n\n/* Notification badge */\n.badge-new {\n animation: pulse 0.8s linear infinite;\n}\n\n@keyframes pulse {\n 0% { transform: scale(1); }\n 50% { transform: scale(1.2); }\n 100% { transform: scale(1); }\n}\n```",
6
+ "expectations": [
7
+ "Flags `linear` easing on the modal open animation: linear motion feels robotic for UI elements entering the screen; recommends `ease-out` for elements entering (ease-out: fast start, gentle stop conveys natural deceleration)",
8
+ "Flags animating `margin-top` and `width` in the modal keyframes: these are layout properties that trigger full reflow on every frame; recommends replacing with `transform: translateY()` and `transform: scale()` or opacity (Ch 3 / Performance: only animate composite properties — transform and opacity)",
9
+ "Flags `transition: all 2s linear` on the button hover: 2 seconds is far too slow for a hover feedback interaction; functional UI feedback should be 100-200ms; recommends `transition: background-color 150ms ease-out` (Ch 1: duration guidance — micro-interactions 100-200ms)",
10
+ "Flags `transition: all` as an anti-pattern: it animates every changing property including layout properties like padding and border-radius that trigger reflow; recommends specifying only the intended properties",
11
+ "Flags animating `padding` and `border-radius` on the button hover for the same layout-thrashing reason",
12
+ "Flags the `linear` easing on the pulse badge animation: while linear is acceptable for continuous looping motion, there is no `prefers-reduced-motion` media query to disable or reduce this infinite animation for users with vestibular disorders",
13
+ "Notes the modal uses `display: none` switching to `display: block` which cannot be animated directly; the animation will jump; recommends using opacity/transform with visibility or pointer-events instead"
14
+ ]
15
+ },
16
+ {
17
+ "id": "eval-02-hover-animation-too-slow",
18
+ "prompt": "Review these CSS hover and focus animations:\n\n```css\n/* Navigation link hover */\n.nav-link {\n color: #333;\n text-decoration: none;\n border-bottom: 2px solid transparent;\n transition: border-bottom-color 1.5s ease-in-out,\n color 1.5s ease-in-out;\n}\n\n.nav-link:hover,\n.nav-link:focus {\n color: #0066cc;\n border-bottom-color: #0066cc;\n}\n\n/* Card hover lift effect */\n.card {\n box-shadow: 0 1px 3px rgba(0,0,0,0.12);\n transition: box-shadow 1.2s ease,\n top 1.2s ease;\n position: relative;\n top: 0;\n}\n\n.card:hover {\n box-shadow: 0 8px 25px rgba(0,0,0,0.15);\n top: -4px;\n}\n\n/* Icon button feedback */\n.icon-btn:active {\n transform: scale(0.9);\n transition: transform 800ms ease;\n}\n```",
19
+ "expectations": [
20
+ "Flags the 1.5s transition on `.nav-link` hover as far too slow for a hover feedback: users expect near-instant response (100-200ms) for hover states; a 1.5s delay makes the interface feel broken or laggy (Ch 1: duration guidance — micro-interactions 100-200ms; functional animations under 1s)",
21
+ "Flags the 1.2s transition on `.card` hover for the same reason: hover lift effects should be 150-250ms to feel responsive",
22
+ "Flags animating `top` on the card hover: `top` is a layout property that triggers reflow; recommends replacing with `transform: translateY(-4px)` which is GPU-accelerated (performance: animate composite properties only)",
23
+ "Flags animating `box-shadow` on the card: box-shadow is not a composite-only property (Ch. 3: only transform and opacity are GPU-composited and avoid layout/paint triggers); recommends replacing with a transform-based approach",
24
+ "Flags the 800ms active/press feedback on `.icon-btn`: press feedback should be the fastest animation in the UI (100-150ms); 800ms means the animation outlasts the press itself and confuses the user",
25
+ "Flags `ease-in-out` on all hover effects: `ease-in-out` is appropriate for elements that move and stay on screen, but for hover state changes `ease-out` is more natural (fast onset, settles gently)",
26
+ "Notes the absence of a `prefers-reduced-motion` media query anywhere in the stylesheet"
27
+ ]
28
+ },
29
+ {
30
+ "id": "eval-03-clean-animation-transform-opacity-consistent-easing",
31
+ "prompt": "Review these CSS and JavaScript animations:\n\n```css\n/* Dropdown menu enter/exit */\n.dropdown {\n opacity: 0;\n transform: translateY(-8px);\n pointer-events: none;\n transition: opacity 200ms ease-out,\n transform 200ms ease-out;\n}\n\n.dropdown.open {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n/* Toast notification slide-in */\n.toast {\n transform: translateX(110%);\n transition: transform 300ms ease-out;\n}\n\n.toast.show {\n transform: translateX(0);\n}\n\n.toast.hide {\n transform: translateX(110%);\n transition: transform 200ms ease-in;\n}\n\n/* Button press feedback */\n.btn:active {\n transform: scale(0.96);\n transition: transform 100ms ease-in;\n}\n\n/* Reduced motion support */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n```\n\n```js\n// Page section fade-in on scroll (Web Animations API)\ndocument.querySelectorAll('.section').forEach(section => {\n const observer = new IntersectionObserver(entries => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n entry.target.animate(\n [{ opacity: 0, transform: 'translateY(20px)' },\n { opacity: 1, transform: 'translateY(0)' }],\n { duration: 400, easing: 'ease-out', fill: 'forwards' }\n );\n observer.unobserve(entry.target);\n }\n });\n }, { threshold: 0.15 });\n observer.observe(section);\n});\n```",
32
+ "expectations": [
33
+ "Recognizes this is a well-designed set of animations and says so explicitly",
34
+ "Praises animating only `transform` and `opacity` throughout: these are GPU-composited properties that avoid layout reflow and paint (performance: composite-only properties)",
35
+ "Praises using `ease-out` for entering elements (dropdown open, toast show, scroll fade-in) and `ease-in` for exiting elements (toast hide) — correct easing directionality (Ch 1: ease-out for entering, ease-in for leaving)",
36
+ "Praises consistent duration scale: 100ms for press feedback, 200ms for dropdown, 300ms for toast entry, 400ms for scroll reveal — all within appropriate ranges and ordered by interaction importance (Ch 1: duration guidance)",
37
+ "Praises the `prefers-reduced-motion` media query that effectively disables all transitions and animations for users who need it (Ch 5: accessibility, vestibular disorders)",
38
+ "Praises `pointer-events: none` on the hidden dropdown to prevent interaction with invisible elements without removing from DOM (correct implementation detail)",
39
+ "Praises using Web Animations API with IntersectionObserver for scroll-triggered animations: avoids scroll-event jank and unobserves after trigger preventing repeat animations (Ch 3: Web Animations API for playback control)",
40
+ "Does NOT manufacture issues to appear thorough; any suggestions are explicitly framed as minor optional improvements"
41
+ ]
42
+ }
43
+ ]
44
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "pass_rate": 0.955,
3
+ "passed": 21,
4
+ "total": 22,
5
+ "baseline_pass_rate": 0.636,
6
+ "baseline_passed": 14,
7
+ "baseline_total": 22,
8
+ "delta": 0.318,
9
+ "model": "default",
10
+ "evals_run": 3,
11
+ "date": "2026-03-28",
12
+ "non_standard_provider": true
13
+ }
@@ -0,0 +1,64 @@
1
+ # After
2
+
3
+ The navigation drawer animation switches to composite-only properties (`transform` + `opacity`), uses `ease-out` easing, a 250ms duration, and respects `prefers-reduced-motion`.
4
+
5
+ ```css
6
+ /* Nav drawer — animate only composite properties (transform, opacity) */
7
+ .nav-drawer {
8
+ /* Position off-screen using transform — not width/height */
9
+ transform: translateX(-280px);
10
+ opacity: 0;
11
+ width: 280px; /* fixed dimensions, never animated */
12
+ height: 100vh;
13
+ overflow: hidden;
14
+ background-color: #1a1a2e;
15
+ /* ease-out: fast start → gentle stop — natural for entering elements (Ch 1) */
16
+ transition:
17
+ transform 250ms ease-out,
18
+ opacity 200ms ease-out;
19
+ /* Hint the browser to promote this element to its own compositor layer */
20
+ will-change: transform;
21
+ }
22
+
23
+ .nav-drawer.open {
24
+ transform: translateX(0);
25
+ opacity: 1;
26
+ }
27
+
28
+ /* Menu items stagger in using animation-delay for follow-through (Ch 1) */
29
+ .nav-drawer .menu-item {
30
+ opacity: 0;
31
+ transform: translateX(-12px);
32
+ transition:
33
+ opacity 180ms ease-out,
34
+ transform 180ms ease-out;
35
+ }
36
+
37
+ .nav-drawer.open .menu-item {
38
+ opacity: 1;
39
+ transform: translateX(0);
40
+ }
41
+
42
+ /* Stagger each item for natural overlapping action */
43
+ .nav-drawer.open .menu-item:nth-child(1) { transition-delay: 60ms; }
44
+ .nav-drawer.open .menu-item:nth-child(2) { transition-delay: 90ms; }
45
+ .nav-drawer.open .menu-item:nth-child(3) { transition-delay: 120ms; }
46
+ .nav-drawer.open .menu-item:nth-child(4) { transition-delay: 150ms; }
47
+
48
+ /* Accessibility: remove all motion for users who prefer it (Ch 5) */
49
+ @media (prefers-reduced-motion: reduce) {
50
+ .nav-drawer,
51
+ .nav-drawer .menu-item {
52
+ transition: opacity 150ms linear !important;
53
+ transform: none !important;
54
+ }
55
+ }
56
+ ```
57
+
58
+ Key improvements:
59
+ - `transform: translateX()` replaces `width`/`height` animation — `transform` and `opacity` are the only composite-only properties that animate on the GPU without triggering layout recalculation (Ch 3: Performance — composite-only properties)
60
+ - Duration reduced from 1.5s to 250ms — functional UI animations should be 200–500ms; 1.5s feels sluggish and blocks the user (Ch 1: Timing and duration)
61
+ - `ease-out` replaces `linear` — entering elements should start fast and slow to a stop; linear easing feels robotic for UI elements (Ch 1: 12 Principles — ease in / ease out)
62
+ - `will-change: transform` promotes the drawer to its own compositor layer, enabling smooth 60fps animation on mobile devices (Ch 3: will-change)
63
+ - Staggered `transition-delay` on menu items creates overlapping action — the drawer and its children don't all stop simultaneously, producing a more natural feel (Ch 1: 12 Principles — follow-through and overlapping action)
64
+ - `@media (prefers-reduced-motion: reduce)` is implemented — users with vestibular disorders receive a simple fade instead of a lateral sweep (Ch 5: Accessibility — prefers-reduced-motion)
@@ -0,0 +1,35 @@
1
+ # Before
2
+
3
+ A CSS animation on a navigation drawer that animates `width` and `height` (layout-triggering properties) with `linear` easing and a 1.5-second duration, with no `prefers-reduced-motion` support.
4
+
5
+ ```css
6
+ .nav-drawer {
7
+ width: 0;
8
+ height: 0;
9
+ overflow: hidden;
10
+ background-color: #1a1a2e;
11
+ }
12
+
13
+ .nav-drawer.open {
14
+ width: 280px;
15
+ height: 100vh;
16
+ /* Animates layout properties — forces browser to recalculate layout
17
+ on every frame, causing jank on low-powered devices */
18
+ transition: width 1.5s linear, height 1.5s linear;
19
+ }
20
+
21
+ .nav-drawer .menu-item {
22
+ opacity: 0;
23
+ /* Also animates layout property margin */
24
+ margin-left: -280px;
25
+ transition: opacity 1.5s linear, margin-left 1.5s linear;
26
+ }
27
+
28
+ .nav-drawer.open .menu-item {
29
+ opacity: 1;
30
+ margin-left: 0;
31
+ }
32
+
33
+ /* No prefers-reduced-motion support — users with vestibular
34
+ disorders experience the full 1.5s sweep animation */
35
+ ```