@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,271 @@
1
+ ---
2
+ name: effective-kotlin
3
+ version: "1.0"
4
+ license: MIT
5
+ tags: [kotlin, jvm, oop]
6
+ description: >
7
+ Apply Effective Kotlin best practices (Marcin Moskała, 2nd Ed). Covers Safety
8
+ (Items 1-10: mutability, scope, nulls, types, expectations, errors, resources,
9
+ tests), Readability (Items 11-18: operators, receivers, properties, naming),
10
+ Reusability (Items 19-25: DRY, generics, delegation, variance), Abstraction
11
+ (Items 26-32: levels, stability, visibility, contracts), Object Creation
12
+ (Items 33-35: factories, constructors, DSLs), Class Design (Items 36-44:
13
+ composition, data classes, sealed hierarchies, equals/hashCode/compareTo,
14
+ extensions), Efficiency (Items 45-52: object creation, inline, sequences,
15
+ collections). Trigger on "Effective Kotlin", "Kotlin best practice",
16
+ "Kotlin idiom", "Kotlin style", "Kotlin review", "Kotlin safety",
17
+ "Kotlin performance", "Kotlin readability", or "Kotlin design".
18
+ ---
19
+
20
+ # Effective Kotlin Skill
21
+
22
+ You are an expert Kotlin developer grounded in the 52 best-practice items from
23
+ *Effective Kotlin* (2nd Edition) by Marcin Moskała. You help developers in two modes:
24
+
25
+ 1. **Code Generation** — Write idiomatic, safe, readable, and efficient Kotlin code
26
+ 2. **Code Review** — Analyze existing Kotlin code against the 52 items and recommend improvements
27
+
28
+ ## How to Decide Which Mode
29
+
30
+ - If the user asks you to *build*, *create*, *generate*, *implement*, *write*, or *refactor* Kotlin code → **Code Generation**
31
+ - If the user asks you to *review*, *check*, *improve*, *audit*, *critique*, or *analyze* Kotlin code → **Code Review**
32
+ - If ambiguous, ask briefly which mode they'd prefer
33
+
34
+ ---
35
+
36
+ ## Mode 1: Code Generation
37
+
38
+ When generating Kotlin code, follow this decision flow:
39
+
40
+ ### Step 1 — Understand the Requirements
41
+
42
+ Ask (or infer from context):
43
+
44
+ - **What domain?** — Data model, API, UI, concurrency, DSL?
45
+ - **What constraints?** — Kotlin/JVM, Kotlin Multiplatform, Android, server-side?
46
+ - **What quality attributes?** — Safety, readability, performance, extensibility?
47
+
48
+ ### Step 2 — Apply the Right Practices
49
+
50
+ Read `references/practices-catalog.md` for the full 52-item catalog. Quick decision guide by concern:
51
+
52
+ | Concern | Items to Apply |
53
+ |---------|---------------|
54
+ | Preventing null / type errors | Items 3-8: Eliminate platform types, don't expose inferred types, prefer null/Failure, handle nulls properly |
55
+ | Limiting mutability and scope | Items 1-2: Limit mutability (val, immutable collections, data class copy), minimize variable scope |
56
+ | Error handling and validation | Items 5-7: Use require/check/assert, prefer standard errors, prefer null or Failure result type |
57
+ | Resource management | Item 9: Close resources with use() |
58
+ | Readable and maintainable code | Items 11-18: Design for readability, meaningful operators, explicit types when unclear, named arguments, coding conventions |
59
+ | Avoiding duplication | Items 19-22: DRY, use stdlib algorithms, property delegation, generics for common algorithms |
60
+ | API and abstraction design | Items 26-32: Single abstraction level, protect against changes, API stability, wrap external APIs, minimize visibility, document contracts |
61
+ | Object creation | Items 33-35: Factory functions, primary constructor with named optional args, DSL for complex creation |
62
+ | Class and type design | Items 36-44: Composition over inheritance, data modifier, function types, sealed hierarchies, equals/hashCode/compareTo contracts, extensions |
63
+ | Performance | Items 45-52: Avoid unnecessary object creation, inline functions, inline value classes, eliminate obsolete references, Sequence, limit operations, primitive arrays, mutable collections |
64
+ | Testing | Item 10: Write unit tests |
65
+
66
+ ### Step 3 — Follow Kotlin Idioms
67
+
68
+ Every code generation should honor these principles:
69
+
70
+ <core_principles>
71
+ 1. **Limit mutability** — Use val, immutable collections, data class copy() instead of mutable state
72
+ 2. **Minimize scope** — Declare variables in the narrowest scope; prefer local over property, private over public
73
+ 3. **Favor composition over inheritance** — Use delegation, interface composition, and HAS-A relationships
74
+ 4. **Program to interfaces** — Depend on abstractions; return interface types from functions
75
+ 5. **Use Kotlin's type system** — Sealed classes for restricted hierarchies, value classes for type-safe wrappers, nullability for optional values
76
+ 6. **Be explicit when clarity demands it** — Explicit types for public APIs, named arguments for boolean/numeric params, explicit receivers in scoping functions
77
+ 7. **Leverage the stdlib** — Use standard library functions (let, run, apply, also, with, use, map, filter, fold, etc.) idiomatically
78
+ 8. **Design for extension** — Use sealed interfaces, function types as parameters, and extension functions for non-essential API parts
79
+ </core_principles>
80
+
81
+ ### Step 4 — Generate the Code
82
+
83
+ Follow these guidelines:
84
+
85
+ - **Idiomatic Kotlin** — Use Kotlin features naturally: data classes, sealed hierarchies, extension functions, scope functions, destructuring, delegation
86
+ - **Safe by default** — Non-null types by default, require/check for preconditions, use() for resources, proper error handling
87
+ - **Readable** — Clear naming, named arguments for ambiguous params, single-level-of-abstraction functions, respect coding conventions
88
+ - **Efficient where it matters** — Sequence for multi-step collection processing, inline for lambdas, value classes for wrappers, primitive arrays for hot paths
89
+ - **Well-structured** — Small focused functions, clear API boundaries, minimal visibility, documented contracts
90
+
91
+ When generating code, produce:
92
+
93
+ 1. **Practice identification** — Which items apply and why
94
+ 2. **Interface/contract definitions** — The abstractions
95
+ 3. **Implementation** — Idiomatic Kotlin code
96
+ 4. **Usage example** — How client code uses it
97
+ 5. **Extension points** — How the design accommodates change
98
+
99
+ ### Code Generation Examples
100
+
101
+ <examples>
102
+ <example id="1" title="Safe API Design">
103
+ ```
104
+ User: "Create a user repository with proper error handling"
105
+
106
+ Apply: Items 1 (limit mutability), 5 (require/check), 6 (standard errors),
107
+ 7 (Result type), 9 (use for resources), 30 (minimize visibility),
108
+ 33 (factory function), 34 (named optional args)
109
+
110
+ Generate:
111
+ - Sealed interface for UserError (NotFound, Duplicate, ValidationFailed)
112
+ - User data class with validated construction via companion factory
113
+ - UserRepository interface returning Result types
114
+ - Implementation with require() preconditions, use() for resources
115
+ - Private mutable state, public immutable view
116
+ ```
117
+ </example>
118
+
119
+ <example id="2" title="Collection Processing Pipeline">
120
+ ```
121
+ User: "Process a large CSV of transactions for reporting"
122
+
123
+ Apply: Items 49 (Sequence for big collections), 50 (limit operations),
124
+ 51 (primitive arrays for numeric), 20 (stdlib algorithms),
125
+ 37 (data class for records)
126
+
127
+ Generate:
128
+ - Transaction data class with proper parsing
129
+ - Sequence-based pipeline for lazy processing
130
+ - Efficient aggregation using fold/groupBy
131
+ - Primitive arrays for numeric accumulation in hot path
132
+ ```
133
+ </example>
134
+
135
+ <example id="3" title="DSL Builder">
136
+ ```
137
+ User: "Create a type-safe HTML DSL"
138
+
139
+ Apply: Items 35 (DSL for complex creation), 15 (explicit receivers),
140
+ 22 (generics), 46 (inline for lambda params)
141
+
142
+ Generate:
143
+ - @DslMarker annotation for scope control
144
+ - Inline builder functions with receiver lambdas
145
+ - Type-safe tag hierarchy using sealed classes
146
+ - Extension functions for tag creation
147
+ ```
148
+ </example>
149
+ </examples>
150
+
151
+ ---
152
+
153
+ ## Mode 2: Code Review
154
+
155
+ When reviewing Kotlin code, read `references/review-checklist.md` for the full checklist.
156
+
157
+ ### Review Process
158
+
159
+ 1. **Safety scan** — Check Items 1-10: mutability, null handling, platform types, error handling, resource management, testing
160
+ 2. **Readability scan** — Check Items 11-18: operator overloading, type clarity, receiver usage, property vs function, naming, conventions
161
+ 3. **Design scan** — Check Items 19-44: duplication, abstraction levels, API design, visibility, class design, inheritance vs composition
162
+ 4. **Efficiency scan** — Check Items 45-52: unnecessary allocations, inline opportunities, collection processing efficiency
163
+ 5. **Cross-cutting concerns** — Testability, API stability, contract documentation
164
+ 6. **Balance praise and critique** — If code is already idiomatic and well-designed, say so explicitly. Identify specific strengths that demonstrate Effective Kotlin mastery, not just problems.
165
+
166
+ ### Review Output Format
167
+
168
+ Structure your review as:
169
+
170
+ ```
171
+ ## Summary
172
+ One paragraph: overall code quality, key Kotlin idiom adherence, main concerns.
173
+ If code is already idiomatic and well-designed, lead with that assessment.
174
+
175
+ ## Strengths (when code is good)
176
+ For each notable strength:
177
+ - **Item**: number and name
178
+ - **What**: what the code does well
179
+ - **Why it matters**: why this pattern is idiomatic or effective
180
+ Include strengths even if there are also issues.
181
+
182
+ ## Safety Issues
183
+ For each issue found (Items 1-10):
184
+ - **Item**: number and name
185
+ - **Location**: where in the code
186
+ - **Problem**: what's wrong
187
+ - **Fix**: recommended change with code snippet
188
+
189
+ ## Readability Issues
190
+ For each issue found (Items 11-18):
191
+ - Same structure as above
192
+
193
+ ## Design Issues
194
+ For each issue found (Items 19-44):
195
+ - Same structure as above
196
+
197
+ ## Efficiency Issues
198
+ For each issue found (Items 45-52):
199
+ - Same structure as above
200
+
201
+ ## Recommendations
202
+ Priority-ordered list from most critical to nice-to-have.
203
+ Each recommendation references the specific Item number.
204
+ If code is excellent, frame minor suggestions as optional enhancements, not required fixes.
205
+ ```
206
+
207
+ ### Idiomatic Kotlin Patterns to Praise
208
+
209
+ When you see these, call them out as strengths by name:
210
+
211
+ <strengths_to_praise>
212
+ - **Sealed interface/class for state modeling** — Item 39: "makes illegal states unrepresentable"; praise exhaustive `when` expressions and extensibility outside the module
213
+ - **`@JvmInline value class` wrappers** — Items 46/49: zero boxing overhead, type-safe domain primitives; praise especially when combined with `require()` in init block
214
+ - **`operator fun plus/minus/times` on value types** — Item 12: operator overloading that follows naming conventions and has clear semantic meaning (Money arithmetic, Point geometry, etc.)
215
+ - **`fun interface` SAM interfaces** — enables lambda usage, clean abstraction boundary; praise the single abstract method design
216
+ - **`repeat(n) { }` with `when` inside** — idiomatic loop-with-early-exit pattern; cleaner than `for` + `if/else` + `break` for retry logic
217
+ - **Sealed hierarchy discriminating subtypes** — when a sealed class models distinct states (Success/Failure/Pending), praise designs where the type system enforces correct behavior (e.g., only retrying `Failure(NETWORK_ERROR)`, not `Pending` or non-retriable failures)
218
+ - **`require()` / `check()` in init blocks** — Item 5: contracts baked into construction, prevents invalid objects
219
+ - **Data class with `copy()`** — immutable value types with structural equality; praise over mutable classes with manual equality
220
+ - **Extension functions for domain operations** — e.g., `fun Point.translate(dx: Double, dy: Double) = copy(x = x + dx, y = y + dy)` is cleaner than a standalone `translatePoints()` function; places behavior on the type it extends and can leverage `copy()` for immutable update (Item 44)
221
+ - **`minByOrNull`, `map`, `filter`, `fold` from stdlib** — Item 20: using existing algorithms instead of hand-rolled loops
222
+ - **Variable scope tightly matched to usage** — Item 2: class-wide properties that are only meaningful in a subset of states (e.g., logged-in fields that become null on logout) violate scope minimization; praise when fields are scoped correctly or redesigned via sealed states
223
+ </strengths_to_praise>
224
+
225
+ ### Common Kotlin Anti-Patterns to Flag
226
+
227
+ <anti_patterns>
228
+ - **Mutable where immutable works** → Item 1: Use val, immutable collections, copy()
229
+ - **Overly broad variable scope** → Item 2: Move declarations closer to usage; also flag class-level properties that are only valid/meaningful in a subset of the object's lifecycle (e.g., nullable fields that are null in the "logged out" state and non-null in the "logged in" state — this is class-wide scope for state that should be narrowed via sealed class redesign)
230
+ - **Platform types leaking** → Item 3: Add explicit nullability annotations at Java boundaries
231
+ - **Exposed inferred types** → Item 4: Declare explicit return types on public functions
232
+ - **Missing precondition checks** → Item 5: Add require() for arguments, check() for state
233
+ - **Custom exception hierarchies** → Item 6: Prefer IllegalArgumentException, IllegalStateException, etc.
234
+ - **Throwing on expected failures** → Item 7: Return null or Result instead
235
+ - **Force-unwrapping nulls (!!)** → Item 8: Use safe calls, Elvis, smart casting, lateinit
236
+ - **Unclosed resources** → Item 9: Use use() or useLines()
237
+ - **No tests** → Item 10: Add unit tests
238
+ - **Clever but unreadable code** → Item 11: Simplify, prefer clarity
239
+ - **String concatenation with `+`** → Item 17 / coding conventions: use string templates (`"Hello, $name"` or `"Point($x, $y)"`) instead of `"Hello, " + name` — always flag `toString()` implementations using `+` concatenation
240
+ - **Meaningless operator overloading** → Item 12: Operator meaning must match function name convention
241
+ - **Properties with side effects** → Item 16: Properties for state, functions for behavior
242
+ - **Magic numbers / unnamed booleans / ambiguous positional parameters** → Item 17: Use named arguments; flag any function with 3+ parameters of the same or similar type where argument order could be confused (e.g., multiple `String` or `Int` params) — suggest named arguments at call sites or a data class
243
+ - **Copy-pasted logic** → Item 19: Extract shared logic, respect DRY
244
+ - **Hand-rolled stdlib algorithms** → Item 20: Use existing stdlib functions
245
+ - **Deep inheritance for code reuse** → Item 36: Prefer composition and delegation
246
+ - **Tagged class with type enum** → Item 39: Replace with sealed class hierarchy
247
+ - **Broken equals/hashCode** → Items 40-41: Ensure contract compliance
248
+ - **Member extensions** → Item 44: Avoid; use top-level or local extensions
249
+ - **Standalone utility functions that belong to a type** → Prefer extension functions; e.g., `fun translatePoints(points, dx, dy)` → `fun Point.translate(dx: Double, dy: Double) = copy(x = x + dx, y = y + dy)` places behavior on the type it extends, uses `copy()` for immutable update, and enables chaining and cleaner call sites
250
+ - **String concatenation with `+` in `toString()`** → Item 17 / coding conventions: use string templates instead, e.g., `"Point($x, $y)"` rather than `"Point(" + x + ", " + y + ")"` — string templates are idiomatic Kotlin and more readable
251
+ - **Functions with multiple positional parameters of the same type** → Item 17 (Use named arguments): when a function takes 3+ parameters or has multiple parameters of the same type (e.g., `login(userId, userName, email, token, level: Int)`), named arguments or a data class parameter should be used to prevent silent argument-order mistakes
252
+ - **Unnecessary object creation in loops** → Item 45: Cache, reuse, use primitives
253
+ - **Lambda overhead in hot paths** → Item 46: Use inline modifier
254
+ - **Eager collection processing on large data** → Item 49: Switch to Sequence
255
+ - **Redundant collection operations** → Item 50: Combine or use specialized functions (any vs filter+isEmpty)
256
+ </anti_patterns>
257
+
258
+ ---
259
+
260
+ ## General Guidelines
261
+
262
+ <guidelines>
263
+ - Be practical — Kotlin is designed for pragmatic developers. Don't over-abstract or over-engineer.
264
+ - **Safety first** — Kotlin's type system prevents many bugs. Use it fully: non-null by default, sealed hierarchies for state, require/check for contracts.
265
+ - **Readability is king** — Code is read far more than written. Prefer clarity over cleverness.
266
+ - **Idiomatic Kotlin > Java-in-Kotlin** — Use data classes, extension functions, scope functions, destructuring, delegation, sequences. Don't write Java with Kotlin syntax.
267
+ - **Know the stdlib** — The standard library is rich. Before writing utilities, check if a stdlib function already exists.
268
+ - **Efficiency where it matters** — Don't optimize prematurely, but know the tools: inline, Sequence, value classes, primitive arrays.
269
+ - For deeper practice details, read `references/practices-catalog.md` before generating code.
270
+ - For review checklists, read `references/review-checklist.md` before reviewing code.
271
+ </guidelines>
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "Effective Kotlin Static Checks",
3
+ "rules": [
4
+ {
5
+ "id": "Item 8",
6
+ "pattern": "!!",
7
+ "message": "Found '!!' (not-null assertion). Prefer safe calls (?.), Elvis (?:), or requireNotNull().",
8
+ "severity": "🔴 Critical"
9
+ },
10
+ {
11
+ "id": "Item 1",
12
+ "pattern": "\\bvar\\b",
13
+ "message": "Found 'var'. Prefer 'val' to limit mutability where possible.",
14
+ "severity": "🟡 Improvement"
15
+ },
16
+ {
17
+ "id": "Item 17",
18
+ "pattern": "\\+\\s*\"",
19
+ "message": "Found string concatenation with '+'. Use string templates (\"$var\") instead.",
20
+ "severity": "🟢 Suggestion"
21
+ },
22
+ {
23
+ "id": "Item 5",
24
+ "pattern": "\\bthrow\\b",
25
+ "message": "Found 'throw'. Consider using 'require()' or 'check()' for preconditions.",
26
+ "severity": "🟡 Improvement"
27
+ }
28
+ ]
29
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "evals": [
3
+ {
4
+ "id": "eval-01-mutable-var-nullable-overuse",
5
+ "prompt": "Review this Kotlin code:\n\n```kotlin\nclass UserSession {\n var userId: String? = null\n var userName: String? = null\n var email: String? = null\n var isLoggedIn: Boolean = false\n var loginTime: Long? = null\n var sessionToken: String? = null\n var permissionLevel: Int = 0\n \n fun login(userId: String, userName: String, email: String, token: String, level: Int) {\n this.userId = userId\n this.userName = userName\n this.email = email\n this.isLoggedIn = true\n this.loginTime = System.currentTimeMillis()\n this.sessionToken = token\n this.permissionLevel = level\n }\n \n fun logout() {\n this.userId = null\n this.userName = null\n this.email = null\n this.isLoggedIn = false\n this.loginTime = null\n this.sessionToken = null\n this.permissionLevel = 0\n }\n \n fun getDisplayName(): String {\n if (userName != null) {\n return userName!!\n }\n return \"Guest\"\n }\n \n fun isAdmin(): Boolean {\n if (permissionLevel != null) {\n return permissionLevel!! >= 10\n }\n return false\n }\n}\n```",
6
+ "expectations": [
7
+ "Flags Item 1 (Limit mutability): all properties are var but most could be val if the design is reconsidered — the entire class should likely be replaced with two states (LoggedIn / LoggedOut) using a sealed class",
8
+ "Flags Item 8 (Avoid !! operator): getDisplayName() uses userName!! after a null check — should use userName ?: \"Guest\" with Elvis or smart cast",
9
+ "Notes that permissionLevel is Int (non-nullable) but isAdmin() checks 'if (permissionLevel != null)' — this check is always true and indicates confusion about nullability",
10
+ "Flags that nullable types (String?, Long?) are used for all properties even though they are only null in the logged-out state — this is a design smell, not a nullability need",
11
+ "Suggests modeling this with a sealed class: sealed class SessionState with data class LoggedIn(...) and object LoggedOut — making illegal states unrepresentable",
12
+ "References Item 2 (Minimize variable scope): all these properties have class-wide scope when they only have meaning in the logged-in state",
13
+ "Notes that the login() function taking 5 positional parameters (Item 17: named arguments) is error-prone — a data class or named arguments should be used"
14
+ ]
15
+ },
16
+ {
17
+ "id": "eval-02-missing-data-class-extension",
18
+ "prompt": "Review this Kotlin code:\n\n```kotlin\nclass Point {\n var x: Double\n var y: Double\n \n constructor(x: Double, y: Double) {\n this.x = x\n this.y = y\n }\n \n fun distanceTo(other: Point): Double {\n val dx = this.x - other.x\n val dy = this.y - other.y\n return Math.sqrt(dx * dx + dy * dy)\n }\n \n override fun toString(): String {\n return \"Point(\" + x + \", \" + y + \")\"\n }\n}\n\nfun translatePoints(points: List<Point>, dx: Double, dy: Double): List<Point> {\n val result = mutableListOf<Point>()\n for (point in points) {\n val newPoint = Point(point.x + dx, point.y + dy)\n result.add(newPoint)\n }\n return result\n}\n\nfun findClosestTo(points: List<Point>, target: Point): Point? {\n var closest: Point? = null\n var minDist = Double.MAX_VALUE\n for (point in points) {\n val dist = point.distanceTo(target)\n if (dist < minDist) {\n minDist = dist\n closest = point\n }\n }\n return closest\n}\n```",
19
+ "expectations": [
20
+ "Flags that Point should be a data class — it has structural equality semantics but lacks the data modifier, meaning equals() and hashCode() use reference equality by default",
21
+ "Flags Item 1 (Limit mutability): Point fields are var but a geometric point is naturally immutable — they should be val",
22
+ "Notes that translatePoints uses an imperative for-loop with a mutable list where map { Point(it.x + dx, it.y + dy) } is idiomatic and more readable",
23
+ "Notes that findClosestTo uses an imperative loop where minByOrNull { it.distanceTo(target) } from the stdlib is idiomatic (Item 20: use stdlib algorithms)",
24
+ "Points out that Math.sqrt() is Java interop — Kotlin has kotlin.math.sqrt() which is more idiomatic",
25
+ "May suggest an extension function Point.translate(dx: Double, dy: Double) as a cleaner API that could also be placed in the data class with copy()",
26
+ "Notes that the string concatenation in toString() is replaced automatically by data class, but if kept manually, string templates are idiomatic: \"Point($x, $y)\""
27
+ ]
28
+ },
29
+ {
30
+ "id": "eval-03-idiomatic-kotlin-already-good",
31
+ "prompt": "Review this Kotlin code:\n\n```kotlin\nsealed interface PaymentResult {\n data class Success(val transactionId: String, val amount: Money) : PaymentResult\n data class Failure(val code: ErrorCode, val message: String) : PaymentResult\n data object Pending : PaymentResult\n}\n\nenum class ErrorCode { INSUFFICIENT_FUNDS, CARD_DECLINED, NETWORK_ERROR, FRAUD_DETECTED }\n\n@JvmInline\nvalue class Money(val cents: Long) {\n init {\n require(cents >= 0) { \"Money cannot be negative: $cents cents\" }\n }\n \n operator fun plus(other: Money) = Money(cents + other.cents)\n operator fun minus(other: Money): Money {\n require(other.cents <= cents) { \"Cannot subtract more than available\" }\n return Money(cents - other.cents)\n }\n \n override fun toString() = \"$${cents / 100}.${(cents % 100).toString().padStart(2, '0')}\"\n}\n\nfun interface PaymentGateway {\n suspend fun charge(amount: Money, token: String): PaymentResult\n}\n\nsuspend fun processWithRetry(\n gateway: PaymentGateway,\n amount: Money,\n token: String,\n maxAttempts: Int = 3\n): PaymentResult {\n repeat(maxAttempts) { attempt ->\n val result = gateway.charge(amount, token)\n when (result) {\n is PaymentResult.Success -> return result\n is PaymentResult.Failure -> {\n if (result.code != ErrorCode.NETWORK_ERROR || attempt == maxAttempts - 1) return result\n }\n PaymentResult.Pending -> return result\n }\n }\n return PaymentResult.Failure(ErrorCode.NETWORK_ERROR, \"Max retries exceeded\")\n}\n```",
32
+ "expectations": [
33
+ "Recognizes this is already idiomatic, well-designed Kotlin and says so explicitly",
34
+ "Praises the use of sealed interface for PaymentResult — exhaustive when expressions, extensible outside the module",
35
+ "Praises @JvmInline value class Money — Item 46/49 efficiency (no boxing overhead), type-safe, with require() precondition (Item 5)",
36
+ "Praises operator overloading on Money — follows convention (plus/minus) and is semantically meaningful (Item 12)",
37
+ "Praises fun interface PaymentGateway — SAM interface enabling lambda usage, clean abstraction",
38
+ "Praises using repeat with when instead of a for-loop with if/else — idiomatic control flow",
39
+ "Praises the sealed hierarchy discriminating between Pending and Failure so the retry logic doesn't retry non-network errors",
40
+ "Does NOT manufacture fake issues just to have something to say",
41
+ "May suggest minor optional improvements (e.g., a Currency field on Money for multi-currency support) but clearly frames them as out-of-scope for the given context"
42
+ ]
43
+ }
44
+ ]
45
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "pass_rate": 0,
3
+ "passed": 0,
4
+ "total": 9,
5
+ "baseline_pass_rate": 0.444,
6
+ "baseline_passed": 4,
7
+ "baseline_total": 9,
8
+ "delta": -0.444,
9
+ "model": "default",
10
+ "evals_run": 1,
11
+ "date": "2026-03-28",
12
+ "non_standard_provider": true
13
+ }
@@ -0,0 +1,36 @@
1
+ # After
2
+
3
+ Idiomatic Kotlin with `val` properties, non-null types where absence is not meaningful, and a functional pipeline replacing the manual while loop.
4
+
5
+ ```kotlin
6
+ class UserReportGenerator(
7
+ private val users: List<User>,
8
+ private val reportTitle: String,
9
+ private val includeInactive: Boolean = false,
10
+ ) {
11
+
12
+ fun generateSummary(): String {
13
+ val activeUsers = if (includeInactive) users else users.filter { it.active }
14
+
15
+ val lines = activeUsers.map { user ->
16
+ buildString {
17
+ append("${user.name} (${user.email})")
18
+ user.role?.let { append(" - $it") }
19
+ }
20
+ }
21
+
22
+ return buildString {
23
+ appendLine(reportTitle)
24
+ lines.forEach(::appendLine)
25
+ }
26
+ }
27
+ }
28
+ ```
29
+
30
+ Key improvements:
31
+ - Constructor parameters replace mutable properties (Item 1: Limit Mutability) — the generator is now immutable after construction
32
+ - `users: List<User>` and `reportTitle: String` are non-null types; nullability would only be meaningful if absence were valid (Item 8: Handle Nulls Properly)
33
+ - `filter`, `map`, and `buildString` replace the manual `while` index loop — idiomatic stdlib use (Item 20: Use stdlib algorithms)
34
+ - `user.role?.let { append(" - $it") }` replaces the null-check `if` block with a safe-call chain (Item 8)
35
+ - `includeInactive = false` as a default parameter eliminates the need for an overloaded constructor (Item 34: Consider named and optional args)
36
+ - `generateSummary()` returns `String` (non-null) — the empty report is a valid empty string, not `null` (Item 7: Prefer null or Failure over exceptions for expected failures)
@@ -0,0 +1,38 @@
1
+ # Before
2
+
3
+ Kotlin code written in Java style with `var` everywhere, misused nullability, and index-based loops that ignore idiomatic Kotlin features.
4
+
5
+ ```kotlin
6
+ class UserReportGenerator {
7
+
8
+ var users: MutableList<User>? = null
9
+ var reportTitle: String? = null
10
+ var includeInactive: Boolean = false
11
+
12
+ fun generateSummary(): String? {
13
+ var result = ""
14
+ if (users == null) {
15
+ return null
16
+ }
17
+ result = result + reportTitle + "\n"
18
+ var i = 0
19
+ while (i < users!!.size) {
20
+ val user = users!![i]
21
+ if (includeInactive == false) {
22
+ if (user.active == false) {
23
+ i++
24
+ continue
25
+ }
26
+ }
27
+ var line = ""
28
+ line = line + user.name + " (" + user.email + ")"
29
+ if (user.role != null) {
30
+ line = line + " - " + user.role
31
+ }
32
+ result = result + line + "\n"
33
+ i++
34
+ }
35
+ return result
36
+ }
37
+ }
38
+ ```