opencode-agent-kit 1.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 (361) hide show
  1. package/README.md +796 -0
  2. package/bin/commands/init.mjs +221 -0
  3. package/bin/init.mjs +21 -0
  4. package/package.json +22 -0
  5. package/template/.opencode/agent-docs/backend/README.md +0 -0
  6. package/template/.opencode/agent-docs/backend/node/BACKEND_PATTERNS.md +82 -0
  7. package/template/.opencode/agent-docs/backend/node/BACKEND_QUICK_START.md +49 -0
  8. package/template/.opencode/agent-docs/frontend/next/README.md +0 -0
  9. package/template/.opencode/agent-docs/frontend/nuxt/API_PATTERNS.md +807 -0
  10. package/template/.opencode/agent-docs/frontend/nuxt/CHEATSHEET.md +676 -0
  11. package/template/.opencode/agent-docs/frontend/nuxt/COMPLETION_REPORT.md +613 -0
  12. package/template/.opencode/agent-docs/frontend/nuxt/EXAMPLES.md +956 -0
  13. package/template/.opencode/agent-docs/frontend/nuxt/INDEX.md +596 -0
  14. package/template/.opencode/agent-docs/frontend/nuxt/MCP_GUIDE.md +881 -0
  15. package/template/.opencode/agent-docs/frontend/nuxt/MENTOR_CURRICULUM_30_DAYS.md +256 -0
  16. package/template/.opencode/agent-docs/frontend/nuxt/MENTOR_CURRICULUM_CHECKLIST.md +156 -0
  17. package/template/.opencode/agent-docs/frontend/nuxt/MENTOR_WEEKLY_ASSIGNMENTS.md +191 -0
  18. package/template/.opencode/agent-docs/frontend/nuxt/QUICK_START.md +509 -0
  19. package/template/.opencode/agent-docs/frontend/nuxt/README.md +506 -0
  20. package/template/.opencode/agent-docs/frontend/nuxt/README_AGENTS.md +140 -0
  21. package/template/.opencode/agent-docs/frontend/nuxt/README_DOCS.md +65 -0
  22. package/template/.opencode/agent-docs/frontend/nuxt/SUMMARY.md +474 -0
  23. package/template/.opencode/agent-docs/frontend/nuxt/TEAM_OPERATING_GUIDE.md +54 -0
  24. package/template/.opencode/agent-docs/frontend/nuxt/TESTING_GUIDE.md +904 -0
  25. package/template/.opencode/agent-docs/frontend/nuxt/WORKFLOWS.md +758 -0
  26. package/template/.opencode/agent-docs/frontend/react/API_PATTERNS.md +187 -0
  27. package/template/.opencode/agent-docs/frontend/react/CHEATSHEET.md +87 -0
  28. package/template/.opencode/agent-docs/frontend/react/INDEX.md +45 -0
  29. package/template/.opencode/agent-docs/frontend/react/QUICK_START.md +43 -0
  30. package/template/.opencode/agent-docs/frontend/react/README.md +159 -0
  31. package/template/.opencode/agent-docs/frontend/vue/README.md +0 -0
  32. package/template/.opencode/agent-docs/mobile/android/README.md +45 -0
  33. package/template/.opencode/agent-docs/mobile/flutter/README.md +44 -0
  34. package/template/.opencode/agents/android-developer.md +418 -0
  35. package/template/.opencode/agents/code-igniter-3-fullstack.md +345 -0
  36. package/template/.opencode/agents/code-reviewer.md +517 -0
  37. package/template/.opencode/agents/database-specialist.md +455 -0
  38. package/template/.opencode/agents/devops-specialist.md +562 -0
  39. package/template/.opencode/agents/flutter-developer.md +556 -0
  40. package/template/.opencode/agents/it-leader.md +911 -0
  41. package/template/.opencode/agents/laravel-advanced.md +691 -0
  42. package/template/.opencode/agents/node-backend-developer.md +343 -0
  43. package/template/.opencode/agents/nuxt-frontend-developer-mentor.md +402 -0
  44. package/template/.opencode/agents/nuxt-frontend-developer.md +1573 -0
  45. package/template/.opencode/agents/react-frontend-developer.md +1017 -0
  46. package/template/.opencode/agents/seo-specialist.md +681 -0
  47. package/template/.opencode/agents/ui-ux-designer.md +783 -0
  48. package/template/.opencode/commands/android-build/command.md +25 -0
  49. package/template/.opencode/commands/android-test/command.md +23 -0
  50. package/template/.opencode/commands/build-fix.md +29 -0
  51. package/template/.opencode/commands/checkpoint.md +74 -0
  52. package/template/.opencode/commands/code-review.md +40 -0
  53. package/template/.opencode/commands/e2e.md +363 -0
  54. package/template/.opencode/commands/eval.md +120 -0
  55. package/template/.opencode/commands/evolve.md +193 -0
  56. package/template/.opencode/commands/flutter-build/command.md +25 -0
  57. package/template/.opencode/commands/flutter-test/command.md +24 -0
  58. package/template/.opencode/commands/go-build.md +183 -0
  59. package/template/.opencode/commands/go-review.md +148 -0
  60. package/template/.opencode/commands/go-test.md +268 -0
  61. package/template/.opencode/commands/gpc-release/command.md +30 -0
  62. package/template/.opencode/commands/instinct-export.md +91 -0
  63. package/template/.opencode/commands/instinct-import.md +142 -0
  64. package/template/.opencode/commands/instinct-status.md +86 -0
  65. package/template/.opencode/commands/learn.md +70 -0
  66. package/template/.opencode/commands/multi-backend.md +158 -0
  67. package/template/.opencode/commands/multi-execute.md +310 -0
  68. package/template/.opencode/commands/multi-frontend.md +158 -0
  69. package/template/.opencode/commands/multi-plan.md +261 -0
  70. package/template/.opencode/commands/multi-workflow.md +183 -0
  71. package/template/.opencode/commands/orchestrate.md +172 -0
  72. package/template/.opencode/commands/plan.md +113 -0
  73. package/template/.opencode/commands/pm2.md +271 -0
  74. package/template/.opencode/commands/python-review.md +297 -0
  75. package/template/.opencode/commands/refactor-clean.md +28 -0
  76. package/template/.opencode/commands/sessions.md +305 -0
  77. package/template/.opencode/commands/setup-pm.md +80 -0
  78. package/template/.opencode/commands/skill-create.md +174 -0
  79. package/template/.opencode/commands/tdd.md +326 -0
  80. package/template/.opencode/commands/test-coverage.md +27 -0
  81. package/template/.opencode/commands/update-codemaps.md +17 -0
  82. package/template/.opencode/commands/update-docs.md +31 -0
  83. package/template/.opencode/commands/verify.md +59 -0
  84. package/template/.opencode/config.example.json +309 -0
  85. package/template/.opencode/config.json +341 -0
  86. package/template/.opencode/contexts/dev.md +20 -0
  87. package/template/.opencode/contexts/research.md +26 -0
  88. package/template/.opencode/contexts/review.md +22 -0
  89. package/template/.opencode/hooks/hooks.json +169 -0
  90. package/template/.opencode/instructions/INSTRUCTIONS.md +388 -0
  91. package/template/.opencode/package.json +5 -0
  92. package/template/.opencode/rules/README.md +82 -0
  93. package/template/.opencode/rules/android/gradle.md +62 -0
  94. package/template/.opencode/rules/android/testing.md +27 -0
  95. package/template/.opencode/rules/common/agents.md +49 -0
  96. package/template/.opencode/rules/common/coding-style.md +48 -0
  97. package/template/.opencode/rules/common/git-workflow.md +45 -0
  98. package/template/.opencode/rules/common/hooks.md +30 -0
  99. package/template/.opencode/rules/common/patterns.md +31 -0
  100. package/template/.opencode/rules/common/performance.md +55 -0
  101. package/template/.opencode/rules/common/security.md +29 -0
  102. package/template/.opencode/rules/common/testing.md +29 -0
  103. package/template/.opencode/rules/flutter/state-management.md +57 -0
  104. package/template/.opencode/rules/flutter/testing.md +42 -0
  105. package/template/.opencode/rules/golang/coding-style.md +26 -0
  106. package/template/.opencode/rules/golang/hooks.md +11 -0
  107. package/template/.opencode/rules/golang/patterns.md +39 -0
  108. package/template/.opencode/rules/golang/security.md +28 -0
  109. package/template/.opencode/rules/golang/testing.md +25 -0
  110. package/template/.opencode/rules/mobile/performance.md +36 -0
  111. package/template/.opencode/rules/python/coding-style.md +37 -0
  112. package/template/.opencode/rules/python/hooks.md +14 -0
  113. package/template/.opencode/rules/python/patterns.md +34 -0
  114. package/template/.opencode/rules/python/security.md +25 -0
  115. package/template/.opencode/rules/python/testing.md +33 -0
  116. package/template/.opencode/rules/typescript/coding-style.md +58 -0
  117. package/template/.opencode/rules/typescript/hooks.md +15 -0
  118. package/template/.opencode/rules/typescript/patterns.md +45 -0
  119. package/template/.opencode/rules/typescript/security.md +21 -0
  120. package/template/.opencode/rules/typescript/testing.md +11 -0
  121. package/template/.opencode/skills/api-documentation/SKILL.md +188 -0
  122. package/template/.opencode/skills/backend-patterns/SKILL.md +587 -0
  123. package/template/.opencode/skills/building-components/SKILL.md +37 -0
  124. package/template/.opencode/skills/building-components/references/accessibility.mdx +819 -0
  125. package/template/.opencode/skills/building-components/references/as-child.mdx +324 -0
  126. package/template/.opencode/skills/building-components/references/composition.mdx +239 -0
  127. package/template/.opencode/skills/building-components/references/data-attributes.mdx +413 -0
  128. package/template/.opencode/skills/building-components/references/definitions.mdx +258 -0
  129. package/template/.opencode/skills/building-components/references/design-tokens.mdx +57 -0
  130. package/template/.opencode/skills/building-components/references/docs.mdx +155 -0
  131. package/template/.opencode/skills/building-components/references/marketplaces.mdx +144 -0
  132. package/template/.opencode/skills/building-components/references/npm.mdx +166 -0
  133. package/template/.opencode/skills/building-components/references/polymorphism.mdx +583 -0
  134. package/template/.opencode/skills/building-components/references/principles.mdx +61 -0
  135. package/template/.opencode/skills/building-components/references/registry.mdx +169 -0
  136. package/template/.opencode/skills/building-components/references/state.mdx +99 -0
  137. package/template/.opencode/skills/building-components/references/styling.mdx +286 -0
  138. package/template/.opencode/skills/building-components/references/types.mdx +191 -0
  139. package/template/.opencode/skills/clickhouse-io/SKILL.md +429 -0
  140. package/template/.opencode/skills/coding-standards/SKILL.md +520 -0
  141. package/template/.opencode/skills/configure-ecc/SKILL.md +298 -0
  142. package/template/.opencode/skills/continuous-learning/SKILL.md +110 -0
  143. package/template/.opencode/skills/continuous-learning/config.json +18 -0
  144. package/template/.opencode/skills/continuous-learning/evaluate-session.sh +60 -0
  145. package/template/.opencode/skills/continuous-learning-v2/SKILL.md +284 -0
  146. package/template/.opencode/skills/continuous-learning-v2/agents/observer.md +137 -0
  147. package/template/.opencode/skills/continuous-learning-v2/agents/start-observer.sh +134 -0
  148. package/template/.opencode/skills/continuous-learning-v2/config.json +41 -0
  149. package/template/.opencode/skills/continuous-learning-v2/hooks/observe.sh +153 -0
  150. package/template/.opencode/skills/continuous-learning-v2/scripts/instinct-cli.py +489 -0
  151. package/template/.opencode/skills/continuous-learning-v2/scripts/test_parse_instinct.py +82 -0
  152. package/template/.opencode/skills/dart-add-unit-test/SKILL.md +122 -0
  153. package/template/.opencode/skills/dart-build-cli-app/SKILL.md +185 -0
  154. package/template/.opencode/skills/dart-collect-coverage/SKILL.md +141 -0
  155. package/template/.opencode/skills/dart-fix-runtime-errors/SKILL.md +166 -0
  156. package/template/.opencode/skills/dart-generate-test-mocks/SKILL.md +155 -0
  157. package/template/.opencode/skills/dart-migrate-to-checks-package/SKILL.md +126 -0
  158. package/template/.opencode/skills/dart-resolve-package-conflicts/SKILL.md +116 -0
  159. package/template/.opencode/skills/dart-run-static-analysis/SKILL.md +104 -0
  160. package/template/.opencode/skills/dart-use-pattern-matching/SKILL.md +146 -0
  161. package/template/.opencode/skills/django-patterns/SKILL.md +733 -0
  162. package/template/.opencode/skills/django-security/SKILL.md +592 -0
  163. package/template/.opencode/skills/django-tdd/SKILL.md +728 -0
  164. package/template/.opencode/skills/django-verification/SKILL.md +460 -0
  165. package/template/.opencode/skills/eval-harness/SKILL.md +227 -0
  166. package/template/.opencode/skills/firebase-basics/SKILL.md +103 -0
  167. package/template/.opencode/skills/firebase-basics/references/additional-skills.md +113 -0
  168. package/template/.opencode/skills/firebase-basics/references/cli-usage.md +31 -0
  169. package/template/.opencode/skills/firebase-basics/references/client-library-usage.md +45 -0
  170. package/template/.opencode/skills/firebase-basics/references/core-concepts.md +61 -0
  171. package/template/.opencode/skills/firebase-basics/references/iac-usage.md +40 -0
  172. package/template/.opencode/skills/firebase-basics/references/iam-security.md +74 -0
  173. package/template/.opencode/skills/firebase-basics/references/mcp-usage.md +63 -0
  174. package/template/.opencode/skills/flutter/SKILL.md +292 -0
  175. package/template/.opencode/skills/flutter-add-integration-test/SKILL.md +163 -0
  176. package/template/.opencode/skills/flutter-add-widget-preview/SKILL.md +145 -0
  177. package/template/.opencode/skills/flutter-add-widget-test/SKILL.md +154 -0
  178. package/template/.opencode/skills/flutter-apply-architecture-best-practices/SKILL.md +162 -0
  179. package/template/.opencode/skills/flutter-build-responsive-layout/SKILL.md +139 -0
  180. package/template/.opencode/skills/flutter-fix-layout-issues/SKILL.md +130 -0
  181. package/template/.opencode/skills/flutter-implement-json-serialization/SKILL.md +153 -0
  182. package/template/.opencode/skills/flutter-setup-declarative-routing/SKILL.md +255 -0
  183. package/template/.opencode/skills/flutter-setup-localization/SKILL.md +210 -0
  184. package/template/.opencode/skills/flutter-use-http-package/SKILL.md +174 -0
  185. package/template/.opencode/skills/frontend-design/SKILL.md +89 -0
  186. package/template/.opencode/skills/frontend-patterns/SKILL.md +631 -0
  187. package/template/.opencode/skills/golang-patterns/SKILL.md +673 -0
  188. package/template/.opencode/skills/golang-testing/SKILL.md +719 -0
  189. package/template/.opencode/skills/impeccable/SKILL.md +165 -0
  190. package/template/.opencode/skills/impeccable/agents/impeccable-asset-producer.md +101 -0
  191. package/template/.opencode/skills/impeccable/reference/adapt.md +190 -0
  192. package/template/.opencode/skills/impeccable/reference/animate.md +175 -0
  193. package/template/.opencode/skills/impeccable/reference/audit.md +133 -0
  194. package/template/.opencode/skills/impeccable/reference/bolder.md +113 -0
  195. package/template/.opencode/skills/impeccable/reference/brand.md +118 -0
  196. package/template/.opencode/skills/impeccable/reference/clarify.md +174 -0
  197. package/template/.opencode/skills/impeccable/reference/codex.md +105 -0
  198. package/template/.opencode/skills/impeccable/reference/cognitive-load.md +106 -0
  199. package/template/.opencode/skills/impeccable/reference/color-and-contrast.md +105 -0
  200. package/template/.opencode/skills/impeccable/reference/colorize.md +154 -0
  201. package/template/.opencode/skills/impeccable/reference/craft.md +123 -0
  202. package/template/.opencode/skills/impeccable/reference/critique.md +273 -0
  203. package/template/.opencode/skills/impeccable/reference/delight.md +302 -0
  204. package/template/.opencode/skills/impeccable/reference/distill.md +111 -0
  205. package/template/.opencode/skills/impeccable/reference/document.md +427 -0
  206. package/template/.opencode/skills/impeccable/reference/extract.md +69 -0
  207. package/template/.opencode/skills/impeccable/reference/harden.md +347 -0
  208. package/template/.opencode/skills/impeccable/reference/heuristics-scoring.md +234 -0
  209. package/template/.opencode/skills/impeccable/reference/interaction-design.md +195 -0
  210. package/template/.opencode/skills/impeccable/reference/layout.md +141 -0
  211. package/template/.opencode/skills/impeccable/reference/live.md +622 -0
  212. package/template/.opencode/skills/impeccable/reference/motion-design.md +109 -0
  213. package/template/.opencode/skills/impeccable/reference/onboard.md +234 -0
  214. package/template/.opencode/skills/impeccable/reference/optimize.md +258 -0
  215. package/template/.opencode/skills/impeccable/reference/overdrive.md +130 -0
  216. package/template/.opencode/skills/impeccable/reference/personas.md +179 -0
  217. package/template/.opencode/skills/impeccable/reference/polish.md +242 -0
  218. package/template/.opencode/skills/impeccable/reference/product.md +62 -0
  219. package/template/.opencode/skills/impeccable/reference/quieter.md +99 -0
  220. package/template/.opencode/skills/impeccable/reference/responsive-design.md +114 -0
  221. package/template/.opencode/skills/impeccable/reference/shape.md +165 -0
  222. package/template/.opencode/skills/impeccable/reference/spatial-design.md +100 -0
  223. package/template/.opencode/skills/impeccable/reference/teach.md +156 -0
  224. package/template/.opencode/skills/impeccable/reference/typeset.md +124 -0
  225. package/template/.opencode/skills/impeccable/reference/typography.md +159 -0
  226. package/template/.opencode/skills/impeccable/reference/ux-writing.md +107 -0
  227. package/template/.opencode/skills/impeccable/scripts/cleanup-deprecated.mjs +284 -0
  228. package/template/.opencode/skills/impeccable/scripts/command-metadata.json +94 -0
  229. package/template/.opencode/skills/impeccable/scripts/critique-storage.mjs +242 -0
  230. package/template/.opencode/skills/impeccable/scripts/design-parser.mjs +820 -0
  231. package/template/.opencode/skills/impeccable/scripts/detect-csp.mjs +198 -0
  232. package/template/.opencode/skills/impeccable/scripts/detect.mjs +21 -0
  233. package/template/.opencode/skills/impeccable/scripts/impeccable-paths.mjs +110 -0
  234. package/template/.opencode/skills/impeccable/scripts/is-generated.mjs +69 -0
  235. package/template/.opencode/skills/impeccable/scripts/live-accept.mjs +595 -0
  236. package/template/.opencode/skills/impeccable/scripts/live-browser-session.js +123 -0
  237. package/template/.opencode/skills/impeccable/scripts/live-browser.js +4860 -0
  238. package/template/.opencode/skills/impeccable/scripts/live-complete.mjs +75 -0
  239. package/template/.opencode/skills/impeccable/scripts/live-completion.mjs +18 -0
  240. package/template/.opencode/skills/impeccable/scripts/live-inject.mjs +446 -0
  241. package/template/.opencode/skills/impeccable/scripts/live-poll.mjs +200 -0
  242. package/template/.opencode/skills/impeccable/scripts/live-resume.mjs +48 -0
  243. package/template/.opencode/skills/impeccable/scripts/live-server.mjs +838 -0
  244. package/template/.opencode/skills/impeccable/scripts/live-session-store.mjs +254 -0
  245. package/template/.opencode/skills/impeccable/scripts/live-status.mjs +47 -0
  246. package/template/.opencode/skills/impeccable/scripts/live-wrap.mjs +632 -0
  247. package/template/.opencode/skills/impeccable/scripts/live.mjs +247 -0
  248. package/template/.opencode/skills/impeccable/scripts/load-context.mjs +141 -0
  249. package/template/.opencode/skills/impeccable/scripts/modern-screenshot.umd.js +14 -0
  250. package/template/.opencode/skills/impeccable/scripts/pin.mjs +214 -0
  251. package/template/.opencode/skills/iterative-retrieval/SKILL.md +202 -0
  252. package/template/.opencode/skills/java-coding-standards/SKILL.md +138 -0
  253. package/template/.opencode/skills/jetpack-compose/.skillfish.json +10 -0
  254. package/template/.opencode/skills/jetpack-compose/SKILL.md +420 -0
  255. package/template/.opencode/skills/jpa-patterns/SKILL.md +141 -0
  256. package/template/.opencode/skills/nutrient-document-processing/SKILL.md +165 -0
  257. package/template/.opencode/skills/nuxt-ui/SKILL.md +334 -0
  258. package/template/.opencode/skills/nuxt-ui/references/components.md +377 -0
  259. package/template/.opencode/skills/nuxt-ui/references/composables.md +127 -0
  260. package/template/.opencode/skills/nuxt-ui/references/layouts/chat.md +266 -0
  261. package/template/.opencode/skills/nuxt-ui/references/layouts/dashboard.md +220 -0
  262. package/template/.opencode/skills/nuxt-ui/references/layouts/docs.md +141 -0
  263. package/template/.opencode/skills/nuxt-ui/references/layouts/editor.md +168 -0
  264. package/template/.opencode/skills/nuxt-ui/references/layouts/page.md +260 -0
  265. package/template/.opencode/skills/nuxt-ui/references/theming.md +427 -0
  266. package/template/.opencode/skills/postgres-patterns/SKILL.md +146 -0
  267. package/template/.opencode/skills/project-guidelines-example/SKILL.md +345 -0
  268. package/template/.opencode/skills/python-patterns/SKILL.md +749 -0
  269. package/template/.opencode/skills/python-testing/SKILL.md +815 -0
  270. package/template/.opencode/skills/security-review/SKILL.md +494 -0
  271. package/template/.opencode/skills/security-review/cloud-infrastructure-security.md +361 -0
  272. package/template/.opencode/skills/shadcn-ui/README.md +248 -0
  273. package/template/.opencode/skills/shadcn-ui/SKILL.md +326 -0
  274. package/template/.opencode/skills/shadcn-ui/examples/auth-layout.tsx +177 -0
  275. package/template/.opencode/skills/shadcn-ui/examples/data-table.tsx +313 -0
  276. package/template/.opencode/skills/shadcn-ui/examples/form-pattern.tsx +177 -0
  277. package/template/.opencode/skills/shadcn-ui/resources/component-catalog.md +481 -0
  278. package/template/.opencode/skills/shadcn-ui/resources/customization-guide.md +516 -0
  279. package/template/.opencode/skills/shadcn-ui/resources/migration-guide.md +463 -0
  280. package/template/.opencode/skills/shadcn-ui/resources/setup-guide.md +412 -0
  281. package/template/.opencode/skills/shadcn-ui/scripts/verify-setup.sh +134 -0
  282. package/template/.opencode/skills/springboot-patterns/SKILL.md +304 -0
  283. package/template/.opencode/skills/springboot-security/SKILL.md +119 -0
  284. package/template/.opencode/skills/springboot-tdd/SKILL.md +157 -0
  285. package/template/.opencode/skills/springboot-verification/SKILL.md +100 -0
  286. package/template/.opencode/skills/strategic-compact/SKILL.md +63 -0
  287. package/template/.opencode/skills/strategic-compact/suggest-compact.sh +52 -0
  288. package/template/.opencode/skills/tdd-workflow/SKILL.md +409 -0
  289. package/template/.opencode/skills/vercel-composition-patterns/AGENTS.md +946 -0
  290. package/template/.opencode/skills/vercel-composition-patterns/SKILL.md +89 -0
  291. package/template/.opencode/skills/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
  292. package/template/.opencode/skills/vercel-composition-patterns/rules/architecture-compound-components.md +112 -0
  293. package/template/.opencode/skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -0
  294. package/template/.opencode/skills/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -0
  295. package/template/.opencode/skills/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
  296. package/template/.opencode/skills/vercel-composition-patterns/rules/state-context-interface.md +191 -0
  297. package/template/.opencode/skills/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -0
  298. package/template/.opencode/skills/vercel-composition-patterns/rules/state-lift-state.md +125 -0
  299. package/template/.opencode/skills/vercel-react-best-practices/AGENTS.md +2934 -0
  300. package/template/.opencode/skills/vercel-react-best-practices/SKILL.md +136 -0
  301. package/template/.opencode/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  302. package/template/.opencode/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
  303. package/template/.opencode/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
  304. package/template/.opencode/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
  305. package/template/.opencode/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
  306. package/template/.opencode/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
  307. package/template/.opencode/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
  308. package/template/.opencode/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
  309. package/template/.opencode/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
  310. package/template/.opencode/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
  311. package/template/.opencode/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
  312. package/template/.opencode/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  313. package/template/.opencode/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
  314. package/template/.opencode/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
  315. package/template/.opencode/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
  316. package/template/.opencode/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
  317. package/template/.opencode/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
  318. package/template/.opencode/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
  319. package/template/.opencode/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
  320. package/template/.opencode/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
  321. package/template/.opencode/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
  322. package/template/.opencode/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
  323. package/template/.opencode/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
  324. package/template/.opencode/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
  325. package/template/.opencode/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
  326. package/template/.opencode/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
  327. package/template/.opencode/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
  328. package/template/.opencode/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
  329. package/template/.opencode/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
  330. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
  331. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  332. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
  333. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
  334. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  335. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  336. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
  337. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
  338. package/template/.opencode/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
  339. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
  340. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
  341. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  342. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
  343. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
  344. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  345. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
  346. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
  347. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  348. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  349. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
  350. package/template/.opencode/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  351. package/template/.opencode/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
  352. package/template/.opencode/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
  353. package/template/.opencode/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
  354. package/template/.opencode/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
  355. package/template/.opencode/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
  356. package/template/.opencode/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
  357. package/template/.opencode/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
  358. package/template/.opencode/skills/verification-loop/SKILL.md +120 -0
  359. package/template/.opencode/skills/web-design-guidelines/SKILL.md +39 -0
  360. package/template/AGENTS.md +32 -0
  361. package/template/opencode.json +354 -0
@@ -0,0 +1,420 @@
1
+ ---
2
+ name: android-jetpack-compose
3
+ user-invocable: false
4
+ description: Use when building Android UIs with Jetpack Compose, managing state with remember/mutableStateOf, or implementing declarative UI patterns.
5
+ allowed-tools:
6
+ - Read
7
+ - Write
8
+ - Edit
9
+ - Bash
10
+ - Grep
11
+ - Glob
12
+ ---
13
+
14
+ # Android - Jetpack Compose
15
+
16
+ Modern declarative UI toolkit for building native Android interfaces.
17
+
18
+ ## Key Concepts
19
+
20
+ ### State Management
21
+
22
+ Compose provides several ways to manage state:
23
+
24
+ - **remember**: Survives recomposition
25
+ - **rememberSaveable**: Survives configuration changes
26
+ - **mutableStateOf**: Creates observable state
27
+ - **derivedStateOf**: Computed state that updates when dependencies change
28
+
29
+ ```kotlin
30
+ @Composable
31
+ fun Counter() {
32
+ var count by remember { mutableStateOf(0) }
33
+
34
+ Column {
35
+ Text("Count: $count")
36
+ Button(onClick = { count++ }) {
37
+ Text("Increment")
38
+ }
39
+ }
40
+ }
41
+
42
+ // With saveable for configuration changes
43
+ @Composable
44
+ fun SearchField() {
45
+ var query by rememberSaveable { mutableStateOf("") }
46
+
47
+ TextField(
48
+ value = query,
49
+ onValueChange = { query = it },
50
+ placeholder = { Text("Search...") }
51
+ )
52
+ }
53
+ ```
54
+
55
+ ### State Hoisting
56
+
57
+ Lift state up to make composables stateless and reusable:
58
+
59
+ ```kotlin
60
+ // Stateless composable
61
+ @Composable
62
+ fun NameInput(
63
+ name: String,
64
+ onNameChange: (String) -> Unit,
65
+ modifier: Modifier = Modifier
66
+ ) {
67
+ TextField(
68
+ value = name,
69
+ onValueChange = onNameChange,
70
+ label = { Text("Name") },
71
+ modifier = modifier
72
+ )
73
+ }
74
+
75
+ // Stateful parent
76
+ @Composable
77
+ fun UserForm() {
78
+ var name by remember { mutableStateOf("") }
79
+
80
+ NameInput(
81
+ name = name,
82
+ onNameChange = { name = it }
83
+ )
84
+ }
85
+ ```
86
+
87
+ ### ViewModel Integration
88
+
89
+ ```kotlin
90
+ class UserViewModel : ViewModel() {
91
+ private val _uiState = MutableStateFlow(UserUiState())
92
+ val uiState: StateFlow<UserUiState> = _uiState.asStateFlow()
93
+
94
+ fun updateName(name: String) {
95
+ _uiState.update { it.copy(name = name) }
96
+ }
97
+
98
+ fun saveUser() {
99
+ viewModelScope.launch {
100
+ _uiState.update { it.copy(isLoading = true) }
101
+ try {
102
+ userRepository.save(_uiState.value.toUser())
103
+ _uiState.update { it.copy(isLoading = false, isSaved = true) }
104
+ } catch (e: Exception) {
105
+ _uiState.update { it.copy(isLoading = false, error = e.message) }
106
+ }
107
+ }
108
+ }
109
+ }
110
+
111
+ @Composable
112
+ fun UserScreen(viewModel: UserViewModel = viewModel()) {
113
+ val uiState by viewModel.uiState.collectAsStateWithLifecycle()
114
+
115
+ UserContent(
116
+ uiState = uiState,
117
+ onNameChange = viewModel::updateName,
118
+ onSave = viewModel::saveUser
119
+ )
120
+ }
121
+ ```
122
+
123
+ ## Best Practices
124
+
125
+ ### Composable Function Guidelines
126
+
127
+ ```kotlin
128
+ // Use Modifier as first optional parameter
129
+ @Composable
130
+ fun CustomCard(
131
+ title: String,
132
+ modifier: Modifier = Modifier,
133
+ onClick: () -> Unit = {}
134
+ ) {
135
+ Card(
136
+ modifier = modifier.clickable(onClick = onClick)
137
+ ) {
138
+ Text(
139
+ text = title,
140
+ modifier = Modifier.padding(16.dp)
141
+ )
142
+ }
143
+ }
144
+
145
+ // Use slot APIs for flexible content
146
+ @Composable
147
+ fun CustomScaffold(
148
+ topBar: @Composable () -> Unit = {},
149
+ bottomBar: @Composable () -> Unit = {},
150
+ content: @Composable (PaddingValues) -> Unit
151
+ ) {
152
+ Scaffold(
153
+ topBar = topBar,
154
+ bottomBar = bottomBar,
155
+ content = content
156
+ )
157
+ }
158
+ ```
159
+
160
+ ### Efficient Recomposition
161
+
162
+ ```kotlin
163
+ // Use keys for list items
164
+ @Composable
165
+ fun UserList(users: List<User>) {
166
+ LazyColumn {
167
+ items(
168
+ items = users,
169
+ key = { it.id } // Stable key for efficient updates
170
+ ) { user ->
171
+ UserItem(user)
172
+ }
173
+ }
174
+ }
175
+
176
+ // Use derivedStateOf for expensive computations
177
+ @Composable
178
+ fun FilteredList(items: List<Item>, query: String) {
179
+ val filteredItems by remember(items, query) {
180
+ derivedStateOf {
181
+ items.filter { it.name.contains(query, ignoreCase = true) }
182
+ }
183
+ }
184
+
185
+ LazyColumn {
186
+ items(filteredItems) { item ->
187
+ ItemRow(item)
188
+ }
189
+ }
190
+ }
191
+ ```
192
+
193
+ ### Side Effects
194
+
195
+ ```kotlin
196
+ // LaunchedEffect for coroutine-based side effects
197
+ @Composable
198
+ fun UserProfile(userId: String, viewModel: UserViewModel) {
199
+ LaunchedEffect(userId) {
200
+ viewModel.loadUser(userId)
201
+ }
202
+
203
+ // UI content
204
+ }
205
+
206
+ // DisposableEffect for cleanup
207
+ @Composable
208
+ fun LifecycleAwareComponent(lifecycle: Lifecycle) {
209
+ DisposableEffect(lifecycle) {
210
+ val observer = LifecycleEventObserver { _, event ->
211
+ // Handle lifecycle events
212
+ }
213
+ lifecycle.addObserver(observer)
214
+
215
+ onDispose {
216
+ lifecycle.removeObserver(observer)
217
+ }
218
+ }
219
+ }
220
+
221
+ // SideEffect for non-suspend side effects
222
+ @Composable
223
+ fun AnalyticsScreen(screenName: String) {
224
+ SideEffect {
225
+ analytics.logScreenView(screenName)
226
+ }
227
+ }
228
+ ```
229
+
230
+ ## Common Patterns
231
+
232
+ ### Navigation with Navigation Compose
233
+
234
+ ```kotlin
235
+ @Composable
236
+ fun AppNavigation() {
237
+ val navController = rememberNavController()
238
+
239
+ NavHost(navController = navController, startDestination = "home") {
240
+ composable("home") {
241
+ HomeScreen(
242
+ onNavigateToDetail = { id ->
243
+ navController.navigate("detail/$id")
244
+ }
245
+ )
246
+ }
247
+ composable(
248
+ route = "detail/{itemId}",
249
+ arguments = listOf(navArgument("itemId") { type = NavType.StringType })
250
+ ) { backStackEntry ->
251
+ val itemId = backStackEntry.arguments?.getString("itemId")
252
+ DetailScreen(itemId = itemId)
253
+ }
254
+ }
255
+ }
256
+ ```
257
+
258
+ ### Material 3 Theming
259
+
260
+ ```kotlin
261
+ @Composable
262
+ fun AppTheme(
263
+ darkTheme: Boolean = isSystemInDarkTheme(),
264
+ content: @Composable () -> Unit
265
+ ) {
266
+ val colorScheme = when {
267
+ darkTheme -> darkColorScheme(
268
+ primary = Purple80,
269
+ secondary = PurpleGrey80,
270
+ tertiary = Pink80
271
+ )
272
+ else -> lightColorScheme(
273
+ primary = Purple40,
274
+ secondary = PurpleGrey40,
275
+ tertiary = Pink40
276
+ )
277
+ }
278
+
279
+ MaterialTheme(
280
+ colorScheme = colorScheme,
281
+ typography = Typography,
282
+ content = content
283
+ )
284
+ }
285
+
286
+ // Using theme values
287
+ @Composable
288
+ fun ThemedCard() {
289
+ Card(
290
+ colors = CardDefaults.cardColors(
291
+ containerColor = MaterialTheme.colorScheme.surfaceVariant
292
+ )
293
+ ) {
294
+ Text(
295
+ text = "Themed content",
296
+ style = MaterialTheme.typography.bodyLarge,
297
+ color = MaterialTheme.colorScheme.onSurfaceVariant
298
+ )
299
+ }
300
+ }
301
+ ```
302
+
303
+ ### Lists and Grids
304
+
305
+ ```kotlin
306
+ @Composable
307
+ fun ProductGrid(products: List<Product>) {
308
+ LazyVerticalGrid(
309
+ columns = GridCells.Adaptive(minSize = 160.dp),
310
+ contentPadding = PaddingValues(16.dp),
311
+ horizontalArrangement = Arrangement.spacedBy(16.dp),
312
+ verticalArrangement = Arrangement.spacedBy(16.dp)
313
+ ) {
314
+ items(products, key = { it.id }) { product ->
315
+ ProductCard(product)
316
+ }
317
+ }
318
+ }
319
+
320
+ // Sticky headers
321
+ @Composable
322
+ fun ContactList(contacts: Map<Char, List<Contact>>) {
323
+ LazyColumn {
324
+ contacts.forEach { (initial, contactsForInitial) ->
325
+ stickyHeader {
326
+ Text(
327
+ text = initial.toString(),
328
+ modifier = Modifier
329
+ .fillMaxWidth()
330
+ .background(MaterialTheme.colorScheme.surface)
331
+ .padding(16.dp),
332
+ style = MaterialTheme.typography.titleMedium
333
+ )
334
+ }
335
+ items(contactsForInitial) { contact ->
336
+ ContactItem(contact)
337
+ }
338
+ }
339
+ }
340
+ }
341
+ ```
342
+
343
+ ## Anti-Patterns
344
+
345
+ ### Avoid Side Effects in Composition
346
+
347
+ Bad:
348
+
349
+ ```kotlin
350
+ @Composable
351
+ fun BadExample(viewModel: ViewModel) {
352
+ viewModel.loadData() // Called on every recomposition!
353
+
354
+ Text("Data loaded")
355
+ }
356
+ ```
357
+
358
+ Good:
359
+
360
+ ```kotlin
361
+ @Composable
362
+ fun GoodExample(viewModel: ViewModel) {
363
+ LaunchedEffect(Unit) {
364
+ viewModel.loadData()
365
+ }
366
+
367
+ Text("Data loaded")
368
+ }
369
+ ```
370
+
371
+ ### Don't Read State in Remember Block
372
+
373
+ Bad:
374
+
375
+ ```kotlin
376
+ @Composable
377
+ fun BadCounter(initial: Int) {
378
+ // Won't update when initial changes
379
+ var count by remember { mutableStateOf(initial) }
380
+ }
381
+ ```
382
+
383
+ Good:
384
+
385
+ ```kotlin
386
+ @Composable
387
+ fun GoodCounter(initial: Int) {
388
+ var count by remember(initial) { mutableStateOf(initial) }
389
+ }
390
+ ```
391
+
392
+ ### Avoid Heavy Computation During Composition
393
+
394
+ Bad:
395
+
396
+ ```kotlin
397
+ @Composable
398
+ fun BadList(items: List<Item>) {
399
+ // Runs on every recomposition
400
+ val sorted = items.sortedBy { it.name }
401
+ LazyColumn { /* ... */ }
402
+ }
403
+ ```
404
+
405
+ Good:
406
+
407
+ ```kotlin
408
+ @Composable
409
+ fun GoodList(items: List<Item>) {
410
+ val sorted by remember(items) {
411
+ derivedStateOf { items.sortedBy { it.name } }
412
+ }
413
+ LazyColumn { /* ... */ }
414
+ }
415
+ ```
416
+
417
+ ## Related Skills
418
+
419
+ - **android-architecture**: MVVM and clean architecture patterns
420
+ - **android-kotlin-coroutines**: Async operations in Compose
@@ -0,0 +1,141 @@
1
+ ---
2
+ name: jpa-patterns
3
+ description: JPA/Hibernate patterns for entity design, relationships, query optimization, transactions, auditing, indexing, pagination, and pooling in Spring Boot.
4
+ ---
5
+
6
+ # JPA/Hibernate Patterns
7
+
8
+ Use for data modeling, repositories, and performance tuning in Spring Boot.
9
+
10
+ ## Entity Design
11
+
12
+ ```java
13
+ @Entity
14
+ @Table(name = "markets", indexes = {
15
+ @Index(name = "idx_markets_slug", columnList = "slug", unique = true)
16
+ })
17
+ @EntityListeners(AuditingEntityListener.class)
18
+ public class MarketEntity {
19
+ @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
20
+ private Long id;
21
+
22
+ @Column(nullable = false, length = 200)
23
+ private String name;
24
+
25
+ @Column(nullable = false, unique = true, length = 120)
26
+ private String slug;
27
+
28
+ @Enumerated(EnumType.STRING)
29
+ private MarketStatus status = MarketStatus.ACTIVE;
30
+
31
+ @CreatedDate private Instant createdAt;
32
+ @LastModifiedDate private Instant updatedAt;
33
+ }
34
+ ```
35
+
36
+ Enable auditing:
37
+ ```java
38
+ @Configuration
39
+ @EnableJpaAuditing
40
+ class JpaConfig {}
41
+ ```
42
+
43
+ ## Relationships and N+1 Prevention
44
+
45
+ ```java
46
+ @OneToMany(mappedBy = "market", cascade = CascadeType.ALL, orphanRemoval = true)
47
+ private List<PositionEntity> positions = new ArrayList<>();
48
+ ```
49
+
50
+ - Default to lazy loading; use `JOIN FETCH` in queries when needed
51
+ - Avoid `EAGER` on collections; use DTO projections for read paths
52
+
53
+ ```java
54
+ @Query("select m from MarketEntity m left join fetch m.positions where m.id = :id")
55
+ Optional<MarketEntity> findWithPositions(@Param("id") Long id);
56
+ ```
57
+
58
+ ## Repository Patterns
59
+
60
+ ```java
61
+ public interface MarketRepository extends JpaRepository<MarketEntity, Long> {
62
+ Optional<MarketEntity> findBySlug(String slug);
63
+
64
+ @Query("select m from MarketEntity m where m.status = :status")
65
+ Page<MarketEntity> findByStatus(@Param("status") MarketStatus status, Pageable pageable);
66
+ }
67
+ ```
68
+
69
+ - Use projections for lightweight queries:
70
+ ```java
71
+ public interface MarketSummary {
72
+ Long getId();
73
+ String getName();
74
+ MarketStatus getStatus();
75
+ }
76
+ Page<MarketSummary> findAllBy(Pageable pageable);
77
+ ```
78
+
79
+ ## Transactions
80
+
81
+ - Annotate service methods with `@Transactional`
82
+ - Use `@Transactional(readOnly = true)` for read paths to optimize
83
+ - Choose propagation carefully; avoid long-running transactions
84
+
85
+ ```java
86
+ @Transactional
87
+ public Market updateStatus(Long id, MarketStatus status) {
88
+ MarketEntity entity = repo.findById(id)
89
+ .orElseThrow(() -> new EntityNotFoundException("Market"));
90
+ entity.setStatus(status);
91
+ return Market.from(entity);
92
+ }
93
+ ```
94
+
95
+ ## Pagination
96
+
97
+ ```java
98
+ PageRequest page = PageRequest.of(pageNumber, pageSize, Sort.by("createdAt").descending());
99
+ Page<MarketEntity> markets = repo.findByStatus(MarketStatus.ACTIVE, page);
100
+ ```
101
+
102
+ For cursor-like pagination, include `id > :lastId` in JPQL with ordering.
103
+
104
+ ## Indexing and Performance
105
+
106
+ - Add indexes for common filters (`status`, `slug`, foreign keys)
107
+ - Use composite indexes matching query patterns (`status, created_at`)
108
+ - Avoid `select *`; project only needed columns
109
+ - Batch writes with `saveAll` and `hibernate.jdbc.batch_size`
110
+
111
+ ## Connection Pooling (HikariCP)
112
+
113
+ Recommended properties:
114
+ ```
115
+ spring.datasource.hikari.maximum-pool-size=20
116
+ spring.datasource.hikari.minimum-idle=5
117
+ spring.datasource.hikari.connection-timeout=30000
118
+ spring.datasource.hikari.validation-timeout=5000
119
+ ```
120
+
121
+ For PostgreSQL LOB handling, add:
122
+ ```
123
+ spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
124
+ ```
125
+
126
+ ## Caching
127
+
128
+ - 1st-level cache is per EntityManager; avoid keeping entities across transactions
129
+ - For read-heavy entities, consider second-level cache cautiously; validate eviction strategy
130
+
131
+ ## Migrations
132
+
133
+ - Use Flyway or Liquibase; never rely on Hibernate auto DDL in production
134
+ - Keep migrations idempotent and additive; avoid dropping columns without plan
135
+
136
+ ## Testing Data Access
137
+
138
+ - Prefer `@DataJpaTest` with Testcontainers to mirror production
139
+ - Assert SQL efficiency using logs: set `logging.level.org.hibernate.SQL=DEBUG` and `logging.level.org.hibernate.orm.jdbc.bind=TRACE` for parameter values
140
+
141
+ **Remember**: Keep entities lean, queries intentional, and transactions short. Prevent N+1 with fetch strategies and projections, and index for your read/write paths.