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,304 @@
1
+ ---
2
+ name: springboot-patterns
3
+ description: Spring Boot architecture patterns, REST API design, layered services, data access, caching, async processing, and logging. Use for Java Spring Boot backend work.
4
+ ---
5
+
6
+ # Spring Boot Development Patterns
7
+
8
+ Spring Boot architecture and API patterns for scalable, production-grade services.
9
+
10
+ ## REST API Structure
11
+
12
+ ```java
13
+ @RestController
14
+ @RequestMapping("/api/markets")
15
+ @Validated
16
+ class MarketController {
17
+ private final MarketService marketService;
18
+
19
+ MarketController(MarketService marketService) {
20
+ this.marketService = marketService;
21
+ }
22
+
23
+ @GetMapping
24
+ ResponseEntity<Page<MarketResponse>> list(
25
+ @RequestParam(defaultValue = "0") int page,
26
+ @RequestParam(defaultValue = "20") int size) {
27
+ Page<Market> markets = marketService.list(PageRequest.of(page, size));
28
+ return ResponseEntity.ok(markets.map(MarketResponse::from));
29
+ }
30
+
31
+ @PostMapping
32
+ ResponseEntity<MarketResponse> create(@Valid @RequestBody CreateMarketRequest request) {
33
+ Market market = marketService.create(request);
34
+ return ResponseEntity.status(HttpStatus.CREATED).body(MarketResponse.from(market));
35
+ }
36
+ }
37
+ ```
38
+
39
+ ## Repository Pattern (Spring Data JPA)
40
+
41
+ ```java
42
+ public interface MarketRepository extends JpaRepository<MarketEntity, Long> {
43
+ @Query("select m from MarketEntity m where m.status = :status order by m.volume desc")
44
+ List<MarketEntity> findActive(@Param("status") MarketStatus status, Pageable pageable);
45
+ }
46
+ ```
47
+
48
+ ## Service Layer with Transactions
49
+
50
+ ```java
51
+ @Service
52
+ public class MarketService {
53
+ private final MarketRepository repo;
54
+
55
+ public MarketService(MarketRepository repo) {
56
+ this.repo = repo;
57
+ }
58
+
59
+ @Transactional
60
+ public Market create(CreateMarketRequest request) {
61
+ MarketEntity entity = MarketEntity.from(request);
62
+ MarketEntity saved = repo.save(entity);
63
+ return Market.from(saved);
64
+ }
65
+ }
66
+ ```
67
+
68
+ ## DTOs and Validation
69
+
70
+ ```java
71
+ public record CreateMarketRequest(
72
+ @NotBlank @Size(max = 200) String name,
73
+ @NotBlank @Size(max = 2000) String description,
74
+ @NotNull @FutureOrPresent Instant endDate,
75
+ @NotEmpty List<@NotBlank String> categories) {}
76
+
77
+ public record MarketResponse(Long id, String name, MarketStatus status) {
78
+ static MarketResponse from(Market market) {
79
+ return new MarketResponse(market.id(), market.name(), market.status());
80
+ }
81
+ }
82
+ ```
83
+
84
+ ## Exception Handling
85
+
86
+ ```java
87
+ @ControllerAdvice
88
+ class GlobalExceptionHandler {
89
+ @ExceptionHandler(MethodArgumentNotValidException.class)
90
+ ResponseEntity<ApiError> handleValidation(MethodArgumentNotValidException ex) {
91
+ String message = ex.getBindingResult().getFieldErrors().stream()
92
+ .map(e -> e.getField() + ": " + e.getDefaultMessage())
93
+ .collect(Collectors.joining(", "));
94
+ return ResponseEntity.badRequest().body(ApiError.validation(message));
95
+ }
96
+
97
+ @ExceptionHandler(AccessDeniedException.class)
98
+ ResponseEntity<ApiError> handleAccessDenied() {
99
+ return ResponseEntity.status(HttpStatus.FORBIDDEN).body(ApiError.of("Forbidden"));
100
+ }
101
+
102
+ @ExceptionHandler(Exception.class)
103
+ ResponseEntity<ApiError> handleGeneric(Exception ex) {
104
+ // Log unexpected errors with stack traces
105
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
106
+ .body(ApiError.of("Internal server error"));
107
+ }
108
+ }
109
+ ```
110
+
111
+ ## Caching
112
+
113
+ Requires `@EnableCaching` on a configuration class.
114
+
115
+ ```java
116
+ @Service
117
+ public class MarketCacheService {
118
+ private final MarketRepository repo;
119
+
120
+ public MarketCacheService(MarketRepository repo) {
121
+ this.repo = repo;
122
+ }
123
+
124
+ @Cacheable(value = "market", key = "#id")
125
+ public Market getById(Long id) {
126
+ return repo.findById(id)
127
+ .map(Market::from)
128
+ .orElseThrow(() -> new EntityNotFoundException("Market not found"));
129
+ }
130
+
131
+ @CacheEvict(value = "market", key = "#id")
132
+ public void evict(Long id) {}
133
+ }
134
+ ```
135
+
136
+ ## Async Processing
137
+
138
+ Requires `@EnableAsync` on a configuration class.
139
+
140
+ ```java
141
+ @Service
142
+ public class NotificationService {
143
+ @Async
144
+ public CompletableFuture<Void> sendAsync(Notification notification) {
145
+ // send email/SMS
146
+ return CompletableFuture.completedFuture(null);
147
+ }
148
+ }
149
+ ```
150
+
151
+ ## Logging (SLF4J)
152
+
153
+ ```java
154
+ @Service
155
+ public class ReportService {
156
+ private static final Logger log = LoggerFactory.getLogger(ReportService.class);
157
+
158
+ public Report generate(Long marketId) {
159
+ log.info("generate_report marketId={}", marketId);
160
+ try {
161
+ // logic
162
+ } catch (Exception ex) {
163
+ log.error("generate_report_failed marketId={}", marketId, ex);
164
+ throw ex;
165
+ }
166
+ return new Report();
167
+ }
168
+ }
169
+ ```
170
+
171
+ ## Middleware / Filters
172
+
173
+ ```java
174
+ @Component
175
+ public class RequestLoggingFilter extends OncePerRequestFilter {
176
+ private static final Logger log = LoggerFactory.getLogger(RequestLoggingFilter.class);
177
+
178
+ @Override
179
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
180
+ FilterChain filterChain) throws ServletException, IOException {
181
+ long start = System.currentTimeMillis();
182
+ try {
183
+ filterChain.doFilter(request, response);
184
+ } finally {
185
+ long duration = System.currentTimeMillis() - start;
186
+ log.info("req method={} uri={} status={} durationMs={}",
187
+ request.getMethod(), request.getRequestURI(), response.getStatus(), duration);
188
+ }
189
+ }
190
+ }
191
+ ```
192
+
193
+ ## Pagination and Sorting
194
+
195
+ ```java
196
+ PageRequest page = PageRequest.of(pageNumber, pageSize, Sort.by("createdAt").descending());
197
+ Page<Market> results = marketService.list(page);
198
+ ```
199
+
200
+ ## Error-Resilient External Calls
201
+
202
+ ```java
203
+ public <T> T withRetry(Supplier<T> supplier, int maxRetries) {
204
+ int attempts = 0;
205
+ while (true) {
206
+ try {
207
+ return supplier.get();
208
+ } catch (Exception ex) {
209
+ attempts++;
210
+ if (attempts >= maxRetries) {
211
+ throw ex;
212
+ }
213
+ try {
214
+ Thread.sleep((long) Math.pow(2, attempts) * 100L);
215
+ } catch (InterruptedException ie) {
216
+ Thread.currentThread().interrupt();
217
+ throw ex;
218
+ }
219
+ }
220
+ }
221
+ }
222
+ ```
223
+
224
+ ## Rate Limiting (Filter + Bucket4j)
225
+
226
+ **Security Note**: The `X-Forwarded-For` header is untrusted by default because clients can spoof it.
227
+ Only use forwarded headers when:
228
+ 1. Your app is behind a trusted reverse proxy (nginx, AWS ALB, etc.)
229
+ 2. You have registered `ForwardedHeaderFilter` as a bean
230
+ 3. You have configured `server.forward-headers-strategy=NATIVE` or `FRAMEWORK` in application properties
231
+ 4. Your proxy is configured to overwrite (not append to) the `X-Forwarded-For` header
232
+
233
+ When `ForwardedHeaderFilter` is properly configured, `request.getRemoteAddr()` will automatically
234
+ return the correct client IP from the forwarded headers. Without this configuration, use
235
+ `request.getRemoteAddr()` directly—it returns the immediate connection IP, which is the only
236
+ trustworthy value.
237
+
238
+ ```java
239
+ @Component
240
+ public class RateLimitFilter extends OncePerRequestFilter {
241
+ private final Map<String, Bucket> buckets = new ConcurrentHashMap<>();
242
+
243
+ /*
244
+ * SECURITY: This filter uses request.getRemoteAddr() to identify clients for rate limiting.
245
+ *
246
+ * If your application is behind a reverse proxy (nginx, AWS ALB, etc.), you MUST configure
247
+ * Spring to handle forwarded headers properly for accurate client IP detection:
248
+ *
249
+ * 1. Set server.forward-headers-strategy=NATIVE (for cloud platforms) or FRAMEWORK in
250
+ * application.properties/yaml
251
+ * 2. If using FRAMEWORK strategy, register ForwardedHeaderFilter:
252
+ *
253
+ * @Bean
254
+ * ForwardedHeaderFilter forwardedHeaderFilter() {
255
+ * return new ForwardedHeaderFilter();
256
+ * }
257
+ *
258
+ * 3. Ensure your proxy overwrites (not appends) the X-Forwarded-For header to prevent spoofing
259
+ * 4. Configure server.tomcat.remoteip.trusted-proxies or equivalent for your container
260
+ *
261
+ * Without this configuration, request.getRemoteAddr() returns the proxy IP, not the client IP.
262
+ * Do NOT read X-Forwarded-For directly—it is trivially spoofable without trusted proxy handling.
263
+ */
264
+ @Override
265
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
266
+ FilterChain filterChain) throws ServletException, IOException {
267
+ // Use getRemoteAddr() which returns the correct client IP when ForwardedHeaderFilter
268
+ // is configured, or the direct connection IP otherwise. Never trust X-Forwarded-For
269
+ // headers directly without proper proxy configuration.
270
+ String clientIp = request.getRemoteAddr();
271
+
272
+ Bucket bucket = buckets.computeIfAbsent(clientIp,
273
+ k -> Bucket.builder()
274
+ .addLimit(Bandwidth.classic(100, Refill.greedy(100, Duration.ofMinutes(1))))
275
+ .build());
276
+
277
+ if (bucket.tryConsume(1)) {
278
+ filterChain.doFilter(request, response);
279
+ } else {
280
+ response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
281
+ }
282
+ }
283
+ }
284
+ ```
285
+
286
+ ## Background Jobs
287
+
288
+ Use Spring’s `@Scheduled` or integrate with queues (e.g., Kafka, SQS, RabbitMQ). Keep handlers idempotent and observable.
289
+
290
+ ## Observability
291
+
292
+ - Structured logging (JSON) via Logback encoder
293
+ - Metrics: Micrometer + Prometheus/OTel
294
+ - Tracing: Micrometer Tracing with OpenTelemetry or Brave backend
295
+
296
+ ## Production Defaults
297
+
298
+ - Prefer constructor injection, avoid field injection
299
+ - Enable `spring.mvc.problemdetails.enabled=true` for RFC 7807 errors (Spring Boot 3+)
300
+ - Configure HikariCP pool sizes for workload, set timeouts
301
+ - Use `@Transactional(readOnly = true)` for queries
302
+ - Enforce null-safety via `@NonNull` and `Optional` where appropriate
303
+
304
+ **Remember**: Keep controllers thin, services focused, repositories simple, and errors handled centrally. Optimize for maintainability and testability.
@@ -0,0 +1,119 @@
1
+ ---
2
+ name: springboot-security
3
+ description: Spring Security best practices for authn/authz, validation, CSRF, secrets, headers, rate limiting, and dependency security in Java Spring Boot services.
4
+ ---
5
+
6
+ # Spring Boot Security Review
7
+
8
+ Use when adding auth, handling input, creating endpoints, or dealing with secrets.
9
+
10
+ ## Authentication
11
+
12
+ - Prefer stateless JWT or opaque tokens with revocation list
13
+ - Use `httpOnly`, `Secure`, `SameSite=Strict` cookies for sessions
14
+ - Validate tokens with `OncePerRequestFilter` or resource server
15
+
16
+ ```java
17
+ @Component
18
+ public class JwtAuthFilter extends OncePerRequestFilter {
19
+ private final JwtService jwtService;
20
+
21
+ public JwtAuthFilter(JwtService jwtService) {
22
+ this.jwtService = jwtService;
23
+ }
24
+
25
+ @Override
26
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
27
+ FilterChain chain) throws ServletException, IOException {
28
+ String header = request.getHeader(HttpHeaders.AUTHORIZATION);
29
+ if (header != null && header.startsWith("Bearer ")) {
30
+ String token = header.substring(7);
31
+ Authentication auth = jwtService.authenticate(token);
32
+ SecurityContextHolder.getContext().setAuthentication(auth);
33
+ }
34
+ chain.doFilter(request, response);
35
+ }
36
+ }
37
+ ```
38
+
39
+ ## Authorization
40
+
41
+ - Enable method security: `@EnableMethodSecurity`
42
+ - Use `@PreAuthorize("hasRole('ADMIN')")` or `@PreAuthorize("@authz.canEdit(#id)")`
43
+ - Deny by default; expose only required scopes
44
+
45
+ ## Input Validation
46
+
47
+ - Use Bean Validation with `@Valid` on controllers
48
+ - Apply constraints on DTOs: `@NotBlank`, `@Email`, `@Size`, custom validators
49
+ - Sanitize any HTML with a whitelist before rendering
50
+
51
+ ## SQL Injection Prevention
52
+
53
+ - Use Spring Data repositories or parameterized queries
54
+ - For native queries, use `:param` bindings; never concatenate strings
55
+
56
+ ## CSRF Protection
57
+
58
+ - For browser session apps, keep CSRF enabled; include token in forms/headers
59
+ - For pure APIs with Bearer tokens, disable CSRF and rely on stateless auth
60
+
61
+ ```java
62
+ http
63
+ .csrf(csrf -> csrf.disable())
64
+ .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
65
+ ```
66
+
67
+ ## Secrets Management
68
+
69
+ - No secrets in source; load from env or vault
70
+ - Keep `application.yml` free of credentials; use placeholders
71
+ - Rotate tokens and DB credentials regularly
72
+
73
+ ## Security Headers
74
+
75
+ ```java
76
+ http
77
+ .headers(headers -> headers
78
+ .contentSecurityPolicy(csp -> csp
79
+ .policyDirectives("default-src 'self'"))
80
+ .frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)
81
+ .xssProtection(Customizer.withDefaults())
82
+ .referrerPolicy(rp -> rp.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.NO_REFERRER)));
83
+ ```
84
+
85
+ ## Rate Limiting
86
+
87
+ - Apply Bucket4j or gateway-level limits on expensive endpoints
88
+ - Log and alert on bursts; return 429 with retry hints
89
+
90
+ ## Dependency Security
91
+
92
+ - Run OWASP Dependency Check / Snyk in CI
93
+ - Keep Spring Boot and Spring Security on supported versions
94
+ - Fail builds on known CVEs
95
+
96
+ ## Logging and PII
97
+
98
+ - Never log secrets, tokens, passwords, or full PAN data
99
+ - Redact sensitive fields; use structured JSON logging
100
+
101
+ ## File Uploads
102
+
103
+ - Validate size, content type, and extension
104
+ - Store outside web root; scan if required
105
+
106
+ ## Checklist Before Release
107
+
108
+ - [ ] Auth tokens validated and expired correctly
109
+ - [ ] Authorization guards on every sensitive path
110
+ - [ ] All inputs validated and sanitized
111
+ - [ ] No string-concatenated SQL
112
+ - [ ] CSRF posture correct for app type
113
+ - [ ] Secrets externalized; none committed
114
+ - [ ] Security headers configured
115
+ - [ ] Rate limiting on APIs
116
+ - [ ] Dependencies scanned and up to date
117
+ - [ ] Logs free of sensitive data
118
+
119
+ **Remember**: Deny by default, validate inputs, least privilege, and secure-by-configuration first.
@@ -0,0 +1,157 @@
1
+ ---
2
+ name: springboot-tdd
3
+ description: Test-driven development for Spring Boot using JUnit 5, Mockito, MockMvc, Testcontainers, and JaCoCo. Use when adding features, fixing bugs, or refactoring.
4
+ ---
5
+
6
+ # Spring Boot TDD Workflow
7
+
8
+ TDD guidance for Spring Boot services with 80%+ coverage (unit + integration).
9
+
10
+ ## When to Use
11
+
12
+ - New features or endpoints
13
+ - Bug fixes or refactors
14
+ - Adding data access logic or security rules
15
+
16
+ ## Workflow
17
+
18
+ 1) Write tests first (they should fail)
19
+ 2) Implement minimal code to pass
20
+ 3) Refactor with tests green
21
+ 4) Enforce coverage (JaCoCo)
22
+
23
+ ## Unit Tests (JUnit 5 + Mockito)
24
+
25
+ ```java
26
+ @ExtendWith(MockitoExtension.class)
27
+ class MarketServiceTest {
28
+ @Mock MarketRepository repo;
29
+ @InjectMocks MarketService service;
30
+
31
+ @Test
32
+ void createsMarket() {
33
+ CreateMarketRequest req = new CreateMarketRequest("name", "desc", Instant.now(), List.of("cat"));
34
+ when(repo.save(any())).thenAnswer(inv -> inv.getArgument(0));
35
+
36
+ Market result = service.create(req);
37
+
38
+ assertThat(result.name()).isEqualTo("name");
39
+ verify(repo).save(any());
40
+ }
41
+ }
42
+ ```
43
+
44
+ Patterns:
45
+ - Arrange-Act-Assert
46
+ - Avoid partial mocks; prefer explicit stubbing
47
+ - Use `@ParameterizedTest` for variants
48
+
49
+ ## Web Layer Tests (MockMvc)
50
+
51
+ ```java
52
+ @WebMvcTest(MarketController.class)
53
+ class MarketControllerTest {
54
+ @Autowired MockMvc mockMvc;
55
+ @MockBean MarketService marketService;
56
+
57
+ @Test
58
+ void returnsMarkets() throws Exception {
59
+ when(marketService.list(any())).thenReturn(Page.empty());
60
+
61
+ mockMvc.perform(get("/api/markets"))
62
+ .andExpect(status().isOk())
63
+ .andExpect(jsonPath("$.content").isArray());
64
+ }
65
+ }
66
+ ```
67
+
68
+ ## Integration Tests (SpringBootTest)
69
+
70
+ ```java
71
+ @SpringBootTest
72
+ @AutoConfigureMockMvc
73
+ @ActiveProfiles("test")
74
+ class MarketIntegrationTest {
75
+ @Autowired MockMvc mockMvc;
76
+
77
+ @Test
78
+ void createsMarket() throws Exception {
79
+ mockMvc.perform(post("/api/markets")
80
+ .contentType(MediaType.APPLICATION_JSON)
81
+ .content("""
82
+ {"name":"Test","description":"Desc","endDate":"2030-01-01T00:00:00Z","categories":["general"]}
83
+ """))
84
+ .andExpect(status().isCreated());
85
+ }
86
+ }
87
+ ```
88
+
89
+ ## Persistence Tests (DataJpaTest)
90
+
91
+ ```java
92
+ @DataJpaTest
93
+ @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
94
+ @Import(TestContainersConfig.class)
95
+ class MarketRepositoryTest {
96
+ @Autowired MarketRepository repo;
97
+
98
+ @Test
99
+ void savesAndFinds() {
100
+ MarketEntity entity = new MarketEntity();
101
+ entity.setName("Test");
102
+ repo.save(entity);
103
+
104
+ Optional<MarketEntity> found = repo.findByName("Test");
105
+ assertThat(found).isPresent();
106
+ }
107
+ }
108
+ ```
109
+
110
+ ## Testcontainers
111
+
112
+ - Use reusable containers for Postgres/Redis to mirror production
113
+ - Wire via `@DynamicPropertySource` to inject JDBC URLs into Spring context
114
+
115
+ ## Coverage (JaCoCo)
116
+
117
+ Maven snippet:
118
+ ```xml
119
+ <plugin>
120
+ <groupId>org.jacoco</groupId>
121
+ <artifactId>jacoco-maven-plugin</artifactId>
122
+ <version>0.8.14</version>
123
+ <executions>
124
+ <execution>
125
+ <goals><goal>prepare-agent</goal></goals>
126
+ </execution>
127
+ <execution>
128
+ <id>report</id>
129
+ <phase>verify</phase>
130
+ <goals><goal>report</goal></goals>
131
+ </execution>
132
+ </executions>
133
+ </plugin>
134
+ ```
135
+
136
+ ## Assertions
137
+
138
+ - Prefer AssertJ (`assertThat`) for readability
139
+ - For JSON responses, use `jsonPath`
140
+ - For exceptions: `assertThatThrownBy(...)`
141
+
142
+ ## Test Data Builders
143
+
144
+ ```java
145
+ class MarketBuilder {
146
+ private String name = "Test";
147
+ MarketBuilder withName(String name) { this.name = name; return this; }
148
+ Market build() { return new Market(null, name, MarketStatus.ACTIVE); }
149
+ }
150
+ ```
151
+
152
+ ## CI Commands
153
+
154
+ - Maven: `mvn -T 4 test` or `mvn verify`
155
+ - Gradle: `./gradlew test jacocoTestReport`
156
+
157
+ **Remember**: Keep tests fast, isolated, and deterministic. Test behavior, not implementation details.
@@ -0,0 +1,100 @@
1
+ ---
2
+ name: springboot-verification
3
+ description: Verification loop for Spring Boot projects: build, static analysis, tests with coverage, security scans, and diff review before release or PR.
4
+ ---
5
+
6
+ # Spring Boot Verification Loop
7
+
8
+ Run before PRs, after major changes, and pre-deploy.
9
+
10
+ ## Phase 1: Build
11
+
12
+ ```bash
13
+ mvn -T 4 clean verify -DskipTests
14
+ # or
15
+ ./gradlew clean assemble -x test
16
+ ```
17
+
18
+ If build fails, stop and fix.
19
+
20
+ ## Phase 2: Static Analysis
21
+
22
+ Maven (common plugins):
23
+ ```bash
24
+ mvn -T 4 spotbugs:check pmd:check checkstyle:check
25
+ ```
26
+
27
+ Gradle (if configured):
28
+ ```bash
29
+ ./gradlew checkstyleMain pmdMain spotbugsMain
30
+ ```
31
+
32
+ ## Phase 3: Tests + Coverage
33
+
34
+ ```bash
35
+ mvn -T 4 test
36
+ mvn jacoco:report # verify 80%+ coverage
37
+ # or
38
+ ./gradlew test jacocoTestReport
39
+ ```
40
+
41
+ Report:
42
+ - Total tests, passed/failed
43
+ - Coverage % (lines/branches)
44
+
45
+ ## Phase 4: Security Scan
46
+
47
+ ```bash
48
+ # Dependency CVEs
49
+ mvn org.owasp:dependency-check-maven:check
50
+ # or
51
+ ./gradlew dependencyCheckAnalyze
52
+
53
+ # Secrets (git)
54
+ git secrets --scan # if configured
55
+ ```
56
+
57
+ ## Phase 5: Lint/Format (optional gate)
58
+
59
+ ```bash
60
+ mvn spotless:apply # if using Spotless plugin
61
+ ./gradlew spotlessApply
62
+ ```
63
+
64
+ ## Phase 6: Diff Review
65
+
66
+ ```bash
67
+ git diff --stat
68
+ git diff
69
+ ```
70
+
71
+ Checklist:
72
+ - No debugging logs left (`System.out`, `log.debug` without guards)
73
+ - Meaningful errors and HTTP statuses
74
+ - Transactions and validation present where needed
75
+ - Config changes documented
76
+
77
+ ## Output Template
78
+
79
+ ```
80
+ VERIFICATION REPORT
81
+ ===================
82
+ Build: [PASS/FAIL]
83
+ Static: [PASS/FAIL] (spotbugs/pmd/checkstyle)
84
+ Tests: [PASS/FAIL] (X/Y passed, Z% coverage)
85
+ Security: [PASS/FAIL] (CVE findings: N)
86
+ Diff: [X files changed]
87
+
88
+ Overall: [READY / NOT READY]
89
+
90
+ Issues to Fix:
91
+ 1. ...
92
+ 2. ...
93
+ ```
94
+
95
+ ## Continuous Mode
96
+
97
+ - Re-run phases on significant changes or every 30–60 minutes in long sessions
98
+ - Keep a short loop: `mvn -T 4 test` + spotbugs for quick feedback
99
+
100
+ **Remember**: Fast feedback beats late surprises. Keep the gate strict—treat warnings as defects in production systems.