cc-codeconductor 1.4.2 → 1.5.1

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 (305) hide show
  1. package/README.md +52 -14
  2. package/dist/domain/product/entities.d.ts +1 -1
  3. package/dist/index.js +811 -354
  4. package/dist/library.js +47 -3
  5. package/dist/validation/schemas.d.ts +183 -21
  6. package/docs/generated/cli.md +16 -0
  7. package/package.json +1 -1
  8. package/presets/agy/README.md +1 -1
  9. package/presets/agy/hooks.json +1 -1
  10. package/presets/agy/scripts/invoke-hook.cjs +20 -5
  11. package/presets/agy/settings.json +1 -1
  12. package/presets/agy/skills/api-versioning/SKILL.md +394 -0
  13. package/presets/agy/skills/astro/SKILL.md +318 -0
  14. package/presets/agy/skills/auth-token-inspector/SKILL.md +30 -0
  15. package/presets/agy/skills/cc-pagespeed/SKILL.md +2 -3
  16. package/presets/agy/skills/code-review/SKILL.md +207 -0
  17. package/presets/agy/skills/django-orm/SKILL.md +460 -0
  18. package/presets/agy/skills/django-uv/SKILL.md +405 -0
  19. package/presets/agy/skills/drizzle-schema-architect/SKILL.md +50 -0
  20. package/presets/agy/skills/fastapi-pydantic-strict/SKILL.md +43 -0
  21. package/presets/agy/skills/jpa-nplusone-detector/SKILL.md +45 -0
  22. package/presets/agy/skills/jpa-postgres/SKILL.md +623 -0
  23. package/presets/agy/skills/livewire-alpine-bridge/SKILL.md +35 -0
  24. package/presets/agy/skills/nextjs-typescript/SKILL.md +390 -0
  25. package/presets/agy/skills/python/SKILL.md +611 -0
  26. package/presets/agy/skills/seo-analytics-injector/SKILL.md +43 -0
  27. package/presets/agy/skills/spring-auth-auditor/SKILL.md +29 -0
  28. package/presets/agy/skills/spring-boot-feature/SKILL.md +563 -0
  29. package/presets/agy/skills/spring-boot-testing-strategy/SKILL.md +475 -0
  30. package/presets/agy/skills/tailwind-responsive-auditor/SKILL.md +29 -0
  31. package/presets/agy/skills/tdd-mutation-tester/SKILL.md +27 -0
  32. package/presets/agy/workflows/cc-api-contract.md +4 -5
  33. package/presets/agy/workflows/cc-backlog.md +4 -5
  34. package/presets/agy/workflows/cc-clarify.md +4 -5
  35. package/presets/agy/workflows/cc-council.md +4 -5
  36. package/presets/agy/workflows/cc-db-migration.md +4 -5
  37. package/presets/agy/workflows/cc-explore.md +4 -5
  38. package/presets/agy/workflows/cc-feature.md +4 -5
  39. package/presets/agy/workflows/cc-fix.md +4 -5
  40. package/presets/agy/workflows/cc-handoff.md +8 -5
  41. package/presets/agy/workflows/cc-iterative.md +4 -5
  42. package/presets/agy/workflows/cc-odd.md +4 -3
  43. package/presets/agy/workflows/cc-openspec.md +5 -6
  44. package/presets/agy/workflows/cc-pagespeed.md +6 -8
  45. package/presets/agy/workflows/cc-prototype.md +4 -5
  46. package/presets/agy/workflows/cc-refactor.md +4 -5
  47. package/presets/agy/workflows/cc-review.md +35 -5
  48. package/presets/agy/workflows/cc-scorecard.md +4 -5
  49. package/presets/agy/workflows/cc-security.md +5 -6
  50. package/presets/agy/workflows/cc-spec-mutation.md +4 -5
  51. package/presets/agy/workflows/cc-tdd-cycle.md +4 -5
  52. package/presets/agy/workflows/cc-test-plan.md +4 -5
  53. package/presets/agy/workflows/cc-triage.md +4 -5
  54. package/presets/claude/CLAUDE.md +6 -5
  55. package/presets/claude/commands/cc/api-contract.md +4 -5
  56. package/presets/claude/commands/cc/backlog.md +4 -5
  57. package/presets/claude/commands/cc/clarify.md +4 -5
  58. package/presets/claude/commands/cc/council.md +4 -5
  59. package/presets/claude/commands/cc/db-migration.md +4 -5
  60. package/presets/claude/commands/cc/explore.md +4 -5
  61. package/presets/claude/commands/cc/feature.md +4 -5
  62. package/presets/claude/commands/cc/fix.md +4 -5
  63. package/presets/claude/commands/cc/handoff.md +8 -5
  64. package/presets/claude/commands/cc/iterative.md +4 -5
  65. package/presets/claude/commands/cc/odd.md +4 -3
  66. package/presets/claude/commands/cc/openspec.md +23 -7
  67. package/presets/claude/commands/cc/pagespeed.md +4 -5
  68. package/presets/claude/commands/cc/prototype.md +4 -5
  69. package/presets/claude/commands/cc/refactor.md +4 -5
  70. package/presets/claude/commands/cc/review.md +37 -5
  71. package/presets/claude/commands/cc/scorecard.md +4 -5
  72. package/presets/claude/commands/cc/security.md +4 -5
  73. package/presets/claude/commands/cc/spec-mutation.md +4 -5
  74. package/presets/claude/commands/cc/tdd-cycle.md +4 -5
  75. package/presets/claude/commands/cc/test-plan.md +4 -5
  76. package/presets/claude/commands/cc/triage.md +4 -5
  77. package/presets/claude/settings.json +33 -79
  78. package/presets/claude/skills/android/SKILL.md +1 -1
  79. package/presets/claude/skills/api-versioning/SKILL.md +1 -1
  80. package/presets/claude/skills/astro/SKILL.md +318 -0
  81. package/presets/claude/skills/auth-token-inspector/SKILL.md +30 -0
  82. package/presets/claude/skills/code-review/SKILL.md +207 -0
  83. package/presets/claude/skills/django-orm/SKILL.md +1 -1
  84. package/presets/claude/skills/django-testing/SKILL.md +1 -1
  85. package/presets/claude/skills/django-uv/SKILL.md +405 -0
  86. package/presets/claude/skills/drizzle-schema-architect/SKILL.md +50 -0
  87. package/presets/claude/skills/fastapi-pydantic-strict/SKILL.md +43 -0
  88. package/presets/claude/skills/jpa-nplusone-detector/SKILL.md +45 -0
  89. package/presets/claude/skills/jpa-postgres/SKILL.md +1 -1
  90. package/presets/claude/skills/livewire-alpine-bridge/SKILL.md +35 -0
  91. package/presets/claude/skills/nextjs-typescript/SKILL.md +390 -0
  92. package/presets/claude/skills/pagespeed-perf/SKILL.md +1 -1
  93. package/presets/claude/skills/python/SKILL.md +1 -1
  94. package/presets/claude/skills/python-django-stack/SKILL.md +1 -1
  95. package/presets/claude/skills/python-fastapi-stack/SKILL.md +1 -1
  96. package/presets/claude/skills/security/SKILL.md +1 -1
  97. package/presets/claude/skills/seo-analytics-injector/SKILL.md +43 -0
  98. package/presets/claude/skills/spring-auth-auditor/SKILL.md +29 -0
  99. package/presets/claude/skills/spring-boot-feature/SKILL.md +1 -1
  100. package/presets/claude/skills/spring-boot-kotlin/SKILL.md +1 -1
  101. package/presets/claude/skills/spring-boot-testing-strategy/SKILL.md +475 -0
  102. package/presets/claude/skills/sqlalchemy/SKILL.md +1 -1
  103. package/presets/claude/skills/tailwind-responsive-auditor/SKILL.md +29 -0
  104. package/presets/claude/skills/tdd-mutation-tester/SKILL.md +27 -0
  105. package/presets/claude/skills/testing-strategy/SKILL.md +1 -1
  106. package/presets/codex/config.toml +2 -0
  107. package/presets/codex/skills/android/SKILL.md +1 -1
  108. package/presets/codex/skills/api-versioning/SKILL.md +1 -1
  109. package/presets/codex/skills/astro/SKILL.md +318 -0
  110. package/presets/codex/skills/auth-token-inspector/SKILL.md +30 -0
  111. package/presets/codex/skills/cc-api-contract/SKILL.md +4 -5
  112. package/presets/codex/skills/cc-backlog/SKILL.md +4 -5
  113. package/presets/codex/skills/cc-clarify/SKILL.md +4 -5
  114. package/presets/codex/skills/cc-council/SKILL.md +10 -5
  115. package/presets/codex/skills/cc-db-migration/SKILL.md +4 -5
  116. package/presets/codex/skills/cc-explore/SKILL.md +4 -5
  117. package/presets/codex/skills/cc-feature/SKILL.md +4 -5
  118. package/presets/codex/skills/cc-fix/SKILL.md +4 -5
  119. package/presets/codex/skills/cc-handoff/SKILL.md +8 -5
  120. package/presets/codex/skills/cc-iterative/SKILL.md +4 -5
  121. package/presets/codex/skills/cc-odd/SKILL.md +4 -3
  122. package/presets/codex/skills/cc-openspec/SKILL.md +12 -7
  123. package/presets/codex/skills/cc-pagespeed/SKILL.md +6 -8
  124. package/presets/codex/skills/cc-prototype/SKILL.md +4 -5
  125. package/presets/codex/skills/cc-refactor/SKILL.md +4 -5
  126. package/presets/codex/skills/cc-review/SKILL.md +35 -5
  127. package/presets/codex/skills/cc-scorecard/SKILL.md +4 -5
  128. package/presets/codex/skills/cc-security/SKILL.md +5 -6
  129. package/presets/codex/skills/cc-spec-mutation/SKILL.md +4 -5
  130. package/presets/codex/skills/cc-tdd-cycle/SKILL.md +4 -5
  131. package/presets/codex/skills/cc-test-plan/SKILL.md +4 -5
  132. package/presets/codex/skills/cc-triage/SKILL.md +4 -5
  133. package/presets/codex/skills/code-review/SKILL.md +207 -0
  134. package/presets/codex/skills/django-orm/SKILL.md +1 -1
  135. package/presets/codex/skills/django-testing/SKILL.md +1 -1
  136. package/presets/codex/skills/django-uv/SKILL.md +405 -0
  137. package/presets/codex/skills/drizzle-schema-architect/SKILL.md +50 -0
  138. package/presets/codex/skills/fastapi-pydantic-strict/SKILL.md +43 -0
  139. package/presets/codex/skills/jpa-nplusone-detector/SKILL.md +45 -0
  140. package/presets/codex/skills/jpa-postgres/SKILL.md +1 -1
  141. package/presets/codex/skills/livewire-alpine-bridge/SKILL.md +35 -0
  142. package/presets/codex/skills/nextjs-typescript/SKILL.md +390 -0
  143. package/presets/codex/skills/pagespeed-perf/SKILL.md +1 -1
  144. package/presets/codex/skills/python/SKILL.md +1 -1
  145. package/presets/codex/skills/python-django-stack/SKILL.md +1 -1
  146. package/presets/codex/skills/python-fastapi-stack/SKILL.md +1 -1
  147. package/presets/codex/skills/security-ai-llm/SKILL.md +43 -0
  148. package/presets/codex/skills/security-blue-team/SKILL.md +43 -0
  149. package/presets/codex/skills/security-cloud/SKILL.md +43 -0
  150. package/presets/codex/skills/security-crypto/SKILL.md +43 -0
  151. package/presets/codex/skills/security-exploit-dev/SKILL.md +45 -0
  152. package/presets/codex/skills/security-grc/SKILL.md +43 -0
  153. package/presets/codex/skills/security-incident-response/SKILL.md +45 -0
  154. package/presets/codex/skills/security-log-analysis/SKILL.md +43 -0
  155. package/presets/codex/skills/security-malware-analysis/SKILL.md +44 -0
  156. package/presets/codex/skills/security-mobile/SKILL.md +43 -0
  157. package/presets/codex/skills/security-network/SKILL.md +43 -0
  158. package/presets/codex/skills/security-ot-ics/SKILL.md +43 -0
  159. package/presets/codex/skills/security-recon/SKILL.md +45 -0
  160. package/presets/codex/skills/security-red-team/SKILL.md +44 -0
  161. package/presets/codex/skills/security-reverse-engineering/SKILL.md +44 -0
  162. package/presets/codex/skills/security-soc-automation/SKILL.md +43 -0
  163. package/presets/codex/skills/security-threat-hunting/SKILL.md +43 -0
  164. package/presets/codex/skills/security-vuln-assessment/SKILL.md +45 -0
  165. package/presets/codex/skills/security-web/SKILL.md +44 -0
  166. package/presets/codex/skills/seo-analytics-injector/SKILL.md +43 -0
  167. package/presets/codex/skills/spring-auth-auditor/SKILL.md +29 -0
  168. package/presets/codex/skills/spring-boot-feature/SKILL.md +2 -2
  169. package/presets/codex/skills/spring-boot-kotlin/SKILL.md +1 -1
  170. package/presets/codex/skills/spring-boot-testing-strategy/SKILL.md +475 -0
  171. package/presets/codex/skills/sqlalchemy/SKILL.md +1 -1
  172. package/presets/codex/skills/tailwind-responsive-auditor/SKILL.md +29 -0
  173. package/presets/codex/skills/tdd-mutation-tester/SKILL.md +27 -0
  174. package/presets/codex/skills/testing-strategy/SKILL.md +1 -1
  175. package/presets/cursor/commands/cc/api-contract.md +4 -5
  176. package/presets/cursor/commands/cc/backlog.md +4 -5
  177. package/presets/cursor/commands/cc/clarify.md +4 -5
  178. package/presets/cursor/commands/cc/council.md +4 -5
  179. package/presets/cursor/commands/cc/db-migration.md +4 -5
  180. package/presets/cursor/commands/cc/explore.md +4 -5
  181. package/presets/cursor/commands/cc/feature.md +4 -5
  182. package/presets/cursor/commands/cc/fix.md +4 -5
  183. package/presets/cursor/commands/cc/handoff.md +8 -5
  184. package/presets/cursor/commands/cc/iterative.md +4 -5
  185. package/presets/cursor/commands/cc/odd.md +4 -3
  186. package/presets/cursor/commands/cc/openspec.md +6 -7
  187. package/presets/cursor/commands/cc/pagespeed.md +6 -8
  188. package/presets/cursor/commands/cc/prototype.md +4 -5
  189. package/presets/cursor/commands/cc/refactor.md +4 -5
  190. package/presets/cursor/commands/cc/review.md +35 -5
  191. package/presets/cursor/commands/cc/scorecard.md +4 -5
  192. package/presets/cursor/commands/cc/security.md +5 -6
  193. package/presets/cursor/commands/cc/spec-mutation.md +4 -5
  194. package/presets/cursor/commands/cc/tdd-cycle.md +4 -5
  195. package/presets/cursor/commands/cc/test-plan.md +4 -5
  196. package/presets/cursor/commands/cc/triage.md +4 -5
  197. package/presets/cursor/skills/android/SKILL.md +1 -1
  198. package/presets/cursor/skills/api-versioning/SKILL.md +2 -1
  199. package/presets/cursor/skills/astro/SKILL.md +1 -1
  200. package/presets/cursor/skills/auth-token-inspector/SKILL.md +1 -1
  201. package/presets/cursor/skills/code-review/SKILL.md +1 -1
  202. package/presets/cursor/skills/django-orm/SKILL.md +3 -5
  203. package/presets/cursor/skills/django-testing/SKILL.md +1 -1
  204. package/presets/cursor/skills/django-uv/SKILL.md +1 -1
  205. package/presets/cursor/skills/drizzle-schema-architect/SKILL.md +1 -1
  206. package/presets/cursor/skills/fastapi-pydantic-strict/SKILL.md +1 -1
  207. package/presets/cursor/skills/jpa-nplusone-detector/SKILL.md +1 -1
  208. package/presets/cursor/skills/jpa-postgres/SKILL.md +2 -4
  209. package/presets/cursor/skills/livewire-alpine-bridge/SKILL.md +1 -1
  210. package/presets/cursor/skills/nextjs-typescript/SKILL.md +1 -1
  211. package/presets/cursor/skills/pagespeed-perf/SKILL.md +1 -1
  212. package/presets/cursor/skills/python/SKILL.md +6 -7
  213. package/presets/cursor/skills/python-django-stack/SKILL.md +1 -1
  214. package/presets/cursor/skills/python-fastapi-stack/SKILL.md +1 -1
  215. package/presets/cursor/skills/security/SKILL.md +1 -1
  216. package/presets/cursor/skills/seo-analytics-injector/SKILL.md +1 -1
  217. package/presets/cursor/skills/spring-auth-auditor/SKILL.md +1 -1
  218. package/presets/cursor/skills/spring-boot-feature/SKILL.md +2 -4
  219. package/presets/cursor/skills/spring-boot-kotlin/SKILL.md +1 -1
  220. package/presets/cursor/skills/spring-boot-testing-strategy/SKILL.md +1 -1
  221. package/presets/cursor/skills/sqlalchemy/SKILL.md +1 -1
  222. package/presets/cursor/skills/tailwind-responsive-auditor/SKILL.md +1 -1
  223. package/presets/cursor/skills/tdd-mutation-tester/SKILL.md +1 -1
  224. package/presets/gemini/commands/cc/api-contract.toml +4 -5
  225. package/presets/gemini/commands/cc/backlog.toml +4 -5
  226. package/presets/gemini/commands/cc/clarify.toml +4 -5
  227. package/presets/gemini/commands/cc/council.toml +4 -5
  228. package/presets/gemini/commands/cc/db-migration.toml +4 -5
  229. package/presets/gemini/commands/cc/explore.toml +4 -5
  230. package/presets/gemini/commands/cc/feature.toml +4 -5
  231. package/presets/gemini/commands/cc/fix.toml +4 -5
  232. package/presets/gemini/commands/cc/handoff.toml +8 -5
  233. package/presets/gemini/commands/cc/iterative.toml +4 -5
  234. package/presets/gemini/commands/cc/odd.toml +4 -3
  235. package/presets/gemini/commands/cc/openspec.toml +6 -7
  236. package/presets/gemini/commands/cc/pagespeed.toml +6 -8
  237. package/presets/gemini/commands/cc/prototype.toml +4 -5
  238. package/presets/gemini/commands/cc/refactor.toml +4 -5
  239. package/presets/gemini/commands/cc/review.toml +35 -5
  240. package/presets/gemini/commands/cc/scorecard.toml +4 -5
  241. package/presets/gemini/commands/cc/security.toml +5 -6
  242. package/presets/gemini/commands/cc/spec-mutation.toml +4 -5
  243. package/presets/gemini/commands/cc/tdd-cycle.toml +4 -5
  244. package/presets/gemini/commands/cc/test-plan.toml +4 -5
  245. package/presets/gemini/commands/cc/triage.toml +4 -5
  246. package/presets/opencode/README.md +45 -52
  247. package/presets/opencode/commands/cc-api-contract.md +4 -5
  248. package/presets/opencode/commands/cc-backlog.md +4 -5
  249. package/presets/opencode/commands/cc-clarify.md +4 -5
  250. package/presets/opencode/commands/cc-council.md +4 -5
  251. package/presets/opencode/commands/cc-db-migration.md +4 -5
  252. package/presets/opencode/commands/cc-explore.md +4 -5
  253. package/presets/opencode/commands/cc-feature.md +4 -5
  254. package/presets/opencode/commands/cc-fix.md +4 -5
  255. package/presets/opencode/commands/cc-handoff.md +8 -5
  256. package/presets/opencode/commands/cc-iterative.md +4 -5
  257. package/presets/opencode/commands/cc-odd.md +4 -3
  258. package/presets/opencode/commands/cc-openspec.md +6 -7
  259. package/presets/opencode/commands/cc-pagespeed.md +6 -8
  260. package/presets/opencode/commands/cc-prototype.md +4 -5
  261. package/presets/opencode/commands/cc-refactor.md +4 -5
  262. package/presets/opencode/commands/cc-review.md +35 -5
  263. package/presets/opencode/commands/cc-scorecard.md +4 -5
  264. package/presets/opencode/commands/cc-security.md +5 -6
  265. package/presets/opencode/commands/cc-spec-mutation.md +4 -5
  266. package/presets/opencode/commands/cc-tdd-cycle.md +4 -5
  267. package/presets/opencode/commands/cc-test-plan.md +4 -5
  268. package/presets/opencode/commands/cc-triage.md +4 -5
  269. package/presets/opencode/opencode.jsonc +1 -1
  270. package/presets/opencode/skills/android/SKILL.md +1 -1
  271. package/presets/opencode/skills/api-versioning/SKILL.md +2 -1
  272. package/presets/opencode/skills/astro/SKILL.md +1 -1
  273. package/presets/opencode/skills/auth-token-inspector/SKILL.md +1 -1
  274. package/presets/opencode/skills/code-review/SKILL.md +1 -1
  275. package/presets/opencode/skills/django-orm/SKILL.md +3 -3
  276. package/presets/opencode/skills/django-testing/SKILL.md +1 -1
  277. package/presets/opencode/skills/django-uv/SKILL.md +1 -1
  278. package/presets/opencode/skills/drizzle-schema-architect/SKILL.md +1 -1
  279. package/presets/opencode/skills/fastapi-pydantic-strict/SKILL.md +1 -1
  280. package/presets/opencode/skills/jpa-nplusone-detector/SKILL.md +1 -1
  281. package/presets/opencode/skills/jpa-postgres/SKILL.md +2 -1
  282. package/presets/opencode/skills/livewire-alpine-bridge/SKILL.md +1 -1
  283. package/presets/opencode/skills/nextjs-typescript/SKILL.md +1 -1
  284. package/presets/opencode/skills/pagespeed-perf/SKILL.md +1 -1
  285. package/presets/opencode/skills/python/SKILL.md +6 -5
  286. package/presets/opencode/skills/python-django-stack/SKILL.md +1 -1
  287. package/presets/opencode/skills/python-fastapi-stack/SKILL.md +1 -1
  288. package/presets/opencode/skills/security/SKILL.md +1 -1
  289. package/presets/opencode/skills/seo-analytics-injector/SKILL.md +1 -1
  290. package/presets/opencode/skills/spring-auth-auditor/SKILL.md +1 -1
  291. package/presets/opencode/skills/spring-boot-feature/SKILL.md +2 -1
  292. package/presets/opencode/skills/spring-boot-kotlin/SKILL.md +1 -1
  293. package/presets/opencode/skills/spring-boot-testing-strategy/SKILL.md +1 -1
  294. package/presets/opencode/skills/sqlalchemy/SKILL.md +1 -1
  295. package/presets/opencode/skills/tailwind-responsive-auditor/SKILL.md +1 -1
  296. package/presets/opencode/skills/tdd-mutation-tester/SKILL.md +1 -1
  297. package/presets/seo-hotel/skills/astro-seo/SKILL.md +1 -1
  298. package/presets/seo-hotel/skills/geo-readiness/SKILL.md +1 -1
  299. package/presets/seo-hotel/skills/off-page/SKILL.md +1 -1
  300. package/presets/seo-hotel/skills/schema-validator/SKILL.md +1 -1
  301. package/presets/seo-hotel/skills/seo-audit/SKILL.md +1 -1
  302. package/presets/shared/invoke-hook.cjs +20 -5
  303. package/src/presets/manifests/codex.yml +3 -0
  304. package/src/presets/models/roles.yml +54 -56
  305. package/src/presets/shared-skills.yml +58 -22
@@ -0,0 +1,394 @@
1
+ ---
2
+ id: api-versioning
3
+ name: api-versioning
4
+ description: >
5
+ Provides expert knowledge for designing, implementing, and managing REST API
6
+ versioning strategies with deprecation workflows.
7
+
8
+ user-invokable: true
9
+ license: MIT
10
+ metadata:
11
+ author: lgzarturo
12
+ category: api
13
+
14
+ compatibility:
15
+ tools: [claude, codex, gemini, agy, opencode]
16
+ stacks:
17
+ languages: [kotlin, java, typescript, python, go]
18
+ frameworks: [spring-boot, spring-mvc, express, fastapi]
19
+
20
+ risk:
21
+ level: high
22
+ can_execute_shell: false
23
+ can_modify_files: true
24
+ requires_network: false
25
+
26
+ inputs:
27
+ - source_files
28
+ - openapi spec files
29
+ - existing controller classes
30
+
31
+ outputs:
32
+ - versioned controller classes
33
+ - OpenAPI spec updates
34
+ - deprecation headers
35
+ - changelog entries
36
+ - contract test scaffolding
37
+
38
+ quality:
39
+ reviewed_by: codeconductor-core
40
+ version: 0.1.0
41
+ ---
42
+
43
+ # API Versioning
44
+
45
+ ## Versioning Strategies
46
+
47
+ ### URL Path Versioning (recommended for breaking changes)
48
+
49
+ ```text
50
+ GET /api/v1/users
51
+ GET /api/v2/users
52
+ ```
53
+
54
+ Tradeoffs:
55
+
56
+ - Explicit and visible in logs, proxies, and browser history
57
+ - Easy to cache at the CDN level — the URL uniquely identifies the resource
58
+ version
59
+ - Easy to route at the load balancer
60
+ - Results in some duplication of controller code
61
+ - Changing the URL violates REST HATEOAS principles, though in practice this is
62
+ acceptable
63
+
64
+ Use this when: you have breaking changes and need maximum visibility and
65
+ cacheability.
66
+
67
+ ### Header Versioning
68
+
69
+ ```text
70
+ GET /api/users
71
+ Accept: application/vnd.myapp+json;version=1
72
+ ```
73
+
74
+ Tradeoffs:
75
+
76
+ - Cleaner URLs
77
+ - Harder to test manually — browsers and curl require extra flags
78
+ - Cannot be bookmarked or linked directly
79
+ - CDN caching requires `Vary: Accept` header, which reduces cache hit rates
80
+
81
+ Use this when: you need clean URLs and your clients are all programmatic (no
82
+ browsers).
83
+
84
+ ### Query Parameter Versioning (avoid)
85
+
86
+ ```text
87
+ GET /api/users?version=1
88
+ ```
89
+
90
+ This approach contaminates resource URLs with transport concerns. The version is
91
+ not part of the resource identity. Do not use it. The only valid exception is
92
+ temporary backward-compat support during a migration window.
93
+
94
+ ## When to Version
95
+
96
+ Version when the change is breaking. Not every change requires a version bump.
97
+
98
+ **Breaking — requires new version:**
99
+
100
+ - Removing a field from a response
101
+ - Renaming a field
102
+ - Changing a field's type (e.g., `string` to `object`)
103
+ - Changing the meaning of an existing field
104
+ - Removing an endpoint
105
+ - Changing required fields in a request
106
+ - Changing status codes in a non-additive way
107
+
108
+ **Not breaking — no version bump needed:**
109
+
110
+ - Adding an optional field to a response
111
+ - Adding a new endpoint
112
+ - Adding an optional request parameter
113
+ - Deprecating a field (marking it, but still returning it)
114
+ - Performance improvements
115
+ - Bug fixes that restore documented behavior
116
+
117
+ ## Deprecation Process
118
+
119
+ When a version or endpoint is being phased out, follow this process:
120
+
121
+ **Step 1: Mark in OpenAPI.**
122
+
123
+ ```yaml
124
+ paths:
125
+ /api/v1/users/{id}:
126
+ get:
127
+ deprecated: true
128
+ description: |
129
+ Deprecated since 2026-05-07. Use /api/v2/users/{id} instead.
130
+ Sunset date: 2026-11-07.
131
+ summary: Get user by ID (deprecated)
132
+ ```
133
+
134
+ **Step 2: Add deprecation headers to responses.**
135
+
136
+ ```kotlin
137
+ @GetMapping("/{id}")
138
+ fun getUserV1(@PathVariable id: UUID, response: HttpServletResponse): ResponseEntity<UserV1Response> {
139
+ response.addHeader("Deprecation", "date=\"Wed, 07 May 2026 00:00:00 GMT\"")
140
+ response.addHeader("Sunset", "Mon, 07 Nov 2026 00:00:00 GMT")
141
+ response.addHeader("Link", "</api/v2/users/$id>; rel=\"successor-version\"")
142
+ return ResponseEntity.ok(userService.getById(id).toV1Response())
143
+ }
144
+ ```
145
+
146
+ **Step 3: Document in CHANGELOG.**
147
+
148
+ ```markdown
149
+ ## Deprecated
150
+
151
+ - `GET /api/v1/users/{id}` — deprecated in favor of `GET /api/v2/users/{id}`.
152
+ Sunset: 2026-11-07.
153
+ ```
154
+
155
+ **Step 4: Maintain dual support.**
156
+
157
+ Keep at least two active major versions at all times. When v3 ships, v1 can be
158
+ removed (v2 and v3 remain active).
159
+
160
+ **Step 5: Communicate the sunset date.**
161
+
162
+ Notify consumers before the sunset date through:
163
+
164
+ - API changelog
165
+ - Developer portal announcements
166
+ - Deprecation headers (machine-readable)
167
+ - Direct contact if you have consumer registration data
168
+
169
+ Do not remove a version without a minimum 6-month notice period. 3 months is the
170
+ absolute minimum if forced.
171
+
172
+ ## OpenAPI Conventions
173
+
174
+ ### One file per version (simple cases)
175
+
176
+ ```text
177
+ openapi-v1.yaml
178
+ openapi-v2.yaml
179
+ ```
180
+
181
+ Each file is self-contained and independently valid.
182
+
183
+ ### Single file with version in info (evolving APIs)
184
+
185
+ ```yaml
186
+ openapi: '3.1.0'
187
+ info:
188
+ title: Users API
189
+ version: '2.0.0'
190
+ ```
191
+
192
+ Use `$ref` to share schemas across versions without duplication.
193
+
194
+ ### Cross-version schema reuse
195
+
196
+ ```yaml
197
+ # schemas/user-base.yaml
198
+ UserBase:
199
+ type: object
200
+ properties:
201
+ id:
202
+ type: string
203
+ format: uuid
204
+ email:
205
+ type: string
206
+
207
+ # openapi-v1.yaml
208
+ components:
209
+ schemas:
210
+ UserResponse:
211
+ allOf:
212
+ - $ref: './schemas/user-base.yaml#/UserBase'
213
+ - properties:
214
+ full_name:
215
+ type: string
216
+
217
+ # openapi-v2.yaml — splits full_name into first_name + last_name
218
+ components:
219
+ schemas:
220
+ UserResponse:
221
+ allOf:
222
+ - $ref: './schemas/user-base.yaml#/UserBase'
223
+ - properties:
224
+ first_name:
225
+ type: string
226
+ last_name:
227
+ type: string
228
+ ```
229
+
230
+ ### Documenting breaking changes
231
+
232
+ Put the breaking change in the endpoint description, not just in a changelog:
233
+
234
+ ```yaml
235
+ /api/v2/users/{id}:
236
+ get:
237
+ description: |
238
+ Returns user details.
239
+
240
+ Breaking changes from v1:
241
+ - `full_name` has been replaced by `first_name` and `last_name`
242
+ ```
243
+
244
+ ## Spring Boot Implementation
245
+
246
+ ### URL path versioning
247
+
248
+ ```kotlin
249
+ // V1 controller — never modify once published
250
+ @RestController
251
+ @RequestMapping("/api/v1/users")
252
+ class UserV1Controller(private val userService: UserService) {
253
+
254
+ @GetMapping("/{id}")
255
+ @Deprecated("Use /api/v2/users/{id}", ReplaceWith("UserV2Controller.getUser()"))
256
+ fun getUser(
257
+ @PathVariable id: UUID,
258
+ response: HttpServletResponse
259
+ ): ResponseEntity<UserV1Response> {
260
+ response.addHeader("Deprecation", "date=\"Wed, 07 May 2026 00:00:00 GMT\"")
261
+ response.addHeader("Sunset", "Mon, 07 Nov 2026 00:00:00 GMT")
262
+ return when (val result = userService.getById(id)) {
263
+ is UserResult.Found -> ResponseEntity.ok(result.user.toV1Response())
264
+ is UserResult.NotFound -> ResponseEntity.notFound().build()
265
+ }
266
+ }
267
+ }
268
+
269
+ // V2 controller — new version, new controller, shared service
270
+ @RestController
271
+ @RequestMapping("/api/v2/users")
272
+ class UserV2Controller(private val userService: UserService) {
273
+
274
+ @GetMapping("/{id}")
275
+ fun getUser(@PathVariable id: UUID): ResponseEntity<UserV2Response> {
276
+ return when (val result = userService.getById(id)) {
277
+ is UserResult.Found -> ResponseEntity.ok(result.user.toV2Response())
278
+ is UserResult.NotFound -> ResponseEntity.notFound().build()
279
+ }
280
+ }
281
+ }
282
+ ```
283
+
284
+ Rules:
285
+
286
+ - Create a new controller for each new version — do not modify the existing one
287
+ - The service layer is shared across versions — only the controller and DTO
288
+ change
289
+ - DTO mapper functions are version-specific: `toV1Response()`, `toV2Response()`
290
+ - Never delete a versioned controller until after the sunset date
291
+
292
+ ### DTO versioning
293
+
294
+ ```kotlin
295
+ // V1 — original shape
296
+ data class UserV1Response(
297
+ val id: UUID,
298
+ val email: String,
299
+ val full_name: String
300
+ )
301
+
302
+ // V2 — breaking change: split full_name
303
+ data class UserV2Response(
304
+ val id: UUID,
305
+ val email: String,
306
+ val first_name: String,
307
+ val last_name: String
308
+ )
309
+
310
+ // Extension functions for mapping
311
+ fun User.toV1Response(): UserV1Response = UserV1Response(
312
+ id = id,
313
+ email = email,
314
+ full_name = "$firstName $lastName"
315
+ )
316
+
317
+ fun User.toV2Response(): UserV2Response = UserV2Response(
318
+ id = id,
319
+ email = email,
320
+ first_name = firstName,
321
+ last_name = lastName
322
+ )
323
+ ```
324
+
325
+ ## Contract Testing
326
+
327
+ Contract tests verify that your API does not break existing consumers before
328
+ changes reach production.
329
+
330
+ **When to run:** in CI, before merging any change that touches a controller,
331
+ DTO, or OpenAPI spec.
332
+
333
+ **Tool: Pact (consumer-driven contracts)**
334
+
335
+ Consumer writes a pact:
336
+
337
+ ```kotlin
338
+ // In the consumer service test
339
+ @ExtendWith(PactConsumerTestExt::class)
340
+ class UserServiceConsumerTest {
341
+
342
+ @Pact(consumer = "order-service", provider = "user-service")
343
+ fun getUserPact(builder: PactDslWithProvider): RequestResponsePact {
344
+ return builder
345
+ .given("user with id exists")
346
+ .uponReceiving("a request for user by id")
347
+ .path("/api/v1/users/123e4567-e89b-12d3-a456-426614174000")
348
+ .method("GET")
349
+ .willRespondWith()
350
+ .status(200)
351
+ .body(LambdaDsl.newJsonBody { body ->
352
+ body.uuid("id")
353
+ body.stringType("email")
354
+ body.stringType("full_name")
355
+ }.build())
356
+ .toPact()
357
+ }
358
+ }
359
+ ```
360
+
361
+ Provider verifies the pact:
362
+
363
+ ```kotlin
364
+ @Provider("user-service")
365
+ @PactFolder("pacts")
366
+ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
367
+ class UserServiceProviderTest {
368
+
369
+ @TestTarget
370
+ lateinit var target: HttpTestTarget
371
+
372
+ @BeforeEach
373
+ fun setUp(@LocalServerPort port: Int) {
374
+ target = HttpTestTarget("localhost", port)
375
+ }
376
+ }
377
+ ```
378
+
379
+ **Rule:** run contract tests in CI before any merge that touches an API surface.
380
+ A broken contract test means a consumer will break in production.
381
+
382
+ ## Test Structure Per Version
383
+
384
+ Each API version must have its own test class:
385
+
386
+ ```text
387
+ src/test/kotlin/{package}/user/
388
+ controller/
389
+ UserV1ControllerTest.kt # tests for v1 endpoints
390
+ UserV2ControllerTest.kt # tests for v2 endpoints
391
+ ```
392
+
393
+ Do not share test cases across versions. V1 behavior must be tested
394
+ independently from V2 — they can diverge.
@@ -0,0 +1,318 @@
1
+ ---
2
+ id: astro
3
+ name: astro
4
+ description: >
5
+ Provides expert knowledge for building Astro 5+ sites with Islands Architecture, Content Collections, TypeScript, and performance-first rendering strategies.
6
+
7
+ user-invokable: true
8
+ license: MIT
9
+ metadata:
10
+ author: lgzarturo
11
+ category: frontend
12
+
13
+ compatibility:
14
+ tools: [claude, codex, gemini, agy, opencode]
15
+ stacks:
16
+ languages: []
17
+ frameworks: []
18
+
19
+ risk:
20
+ level: low
21
+ can_execute_shell: false
22
+ can_modify_files: true
23
+ requires_network: false
24
+
25
+ inputs: []
26
+
27
+ outputs: []
28
+
29
+ quality:
30
+ reviewed_by: codeconductor-core
31
+ version: 0.1.0
32
+ ---
33
+
34
+
35
+
36
+ # Astro
37
+
38
+ ## Islands Architecture
39
+
40
+ Astro renders everything to static HTML by default. JavaScript ships only for
41
+ components that explicitly opt in — these are called Islands.
42
+
43
+ ### Hydration Directives
44
+
45
+ | Directive | When JS loads | Use case |
46
+ |-----------|--------------|----------|
47
+ | `client:load` | On page load | Interactive above-the-fold UI |
48
+ | `client:idle` | When browser is idle | Non-critical interactive widgets |
49
+ | `client:visible` | When element enters viewport | Below-the-fold islands |
50
+ | `client:media` | When CSS media query matches | Responsive interactive components |
51
+ | `client:only` | Client-only, no SSR | Components that require the DOM (e.g., charting libs) |
52
+
53
+ ```astro
54
+ ---
55
+ import Counter from '../components/Counter.tsx';
56
+ import HeavyChart from '../components/HeavyChart.tsx';
57
+ import MobileNav from '../components/MobileNav.tsx';
58
+ ---
59
+
60
+ <!-- Hydrates immediately — user interacts right away -->
61
+ <Counter client:load />
62
+
63
+ <!-- Hydrates when scrolled into view — saves initial JS -->
64
+ <HeavyChart client:visible />
65
+
66
+ <!-- Only on mobile, only when query matches -->
67
+ <MobileNav client:media="(max-width: 768px)" />
68
+ ```
69
+
70
+ Rules:
71
+
72
+ - Default to no hydration directive — most UI does not need JavaScript
73
+ - `client:load` is the most expensive directive; use it sparingly
74
+ - `client:only` skips server rendering entirely — the component receives no
75
+ props from the server; pass all data via props or fetch inside the component
76
+ - Do not use `client:load` for components that could use `client:visible`
77
+
78
+ ### Framework Components Inside Astro
79
+
80
+ ```astro
81
+ ---
82
+ import ReactButton from './Button.tsx'; // React island
83
+ import VueWidget from './Widget.vue'; // Vue island
84
+ ---
85
+
86
+ <!-- Both can coexist on the same page -->
87
+ <ReactButton client:idle label="Click me" />
88
+ <VueWidget client:visible />
89
+ ```
90
+
91
+ Each framework ships its own runtime only when at least one island of that
92
+ framework is on the page.
93
+
94
+ ## Content Collections
95
+
96
+ Content Collections provide type-safe access to Markdown, MDX, and data files.
97
+ Define schemas in `src/content/config.ts`.
98
+
99
+ ### Schema Definition
100
+
101
+ ```typescript
102
+ // src/content/config.ts
103
+ import { defineCollection, z } from 'astro:content';
104
+
105
+ const blog = defineCollection({
106
+ type: 'content', // .md or .mdx files
107
+ schema: z.object({
108
+ title: z.string(),
109
+ description: z.string(),
110
+ pubDate: z.coerce.date(),
111
+ updatedDate: z.coerce.date().optional(),
112
+ author: z.string().default('Anonymous'),
113
+ tags: z.array(z.string()).default([]),
114
+ draft: z.boolean().default(false),
115
+ image: z.object({
116
+ src: z.string(),
117
+ alt: z.string(),
118
+ }).optional(),
119
+ }),
120
+ });
121
+
122
+ const docs = defineCollection({
123
+ type: 'content',
124
+ schema: z.object({
125
+ title: z.string(),
126
+ order: z.number(),
127
+ section: z.enum(['guide', 'reference', 'tutorial']),
128
+ }),
129
+ });
130
+
131
+ export const collections = { blog, docs };
132
+ ```
133
+
134
+ ### Querying Collections
135
+
136
+ ```astro
137
+ ---
138
+ import { getCollection, getEntry } from 'astro:content';
139
+
140
+ // All published posts, sorted by date
141
+ const posts = (await getCollection('blog', ({ data }) => !data.draft))
142
+ .sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
143
+
144
+ // Single entry by slug
145
+ const post = await getEntry('blog', 'my-first-post');
146
+ const { Content } = await post.render();
147
+ ---
148
+
149
+ {posts.map(post => (
150
+ <article>
151
+ <h2><a href={`/blog/${post.slug}`}>{post.data.title}</a></h2>
152
+ <time>{post.data.pubDate.toLocaleDateString()}</time>
153
+ </article>
154
+ ))}
155
+ ```
156
+
157
+ ### Dynamic Routes from Collections
158
+
159
+ ```astro
160
+ ---
161
+ // src/pages/blog/[slug].astro
162
+ import { getCollection } from 'astro:content';
163
+
164
+ export async function getStaticPaths() {
165
+ const posts = await getCollection('blog');
166
+ return posts.map(post => ({
167
+ params: { slug: post.slug },
168
+ props: { post },
169
+ }));
170
+ }
171
+
172
+ const { post } = Astro.props;
173
+ const { Content, headings } = await post.render();
174
+ ---
175
+
176
+ <article>
177
+ <h1>{post.data.title}</h1>
178
+ <Content />
179
+ </article>
180
+ ```
181
+
182
+ ## Rendering Strategies
183
+
184
+ ### SSG (Static Site Generation) — default
185
+
186
+ Every page is pre-rendered at build time. Best for content that does not change
187
+ per request.
188
+
189
+ ```javascript
190
+ // astro.config.mjs — no output config needed; SSG is the default
191
+ export default defineConfig({
192
+ site: 'https://example.com',
193
+ });
194
+ ```
195
+
196
+ ### SSR (Server-Side Rendering)
197
+
198
+ Renders pages on each request. Required for: authenticated routes, personalized
199
+ content, live data.
200
+
201
+ ```javascript
202
+ // astro.config.mjs
203
+ import node from '@astrojs/node';
204
+
205
+ export default defineConfig({
206
+ output: 'server',
207
+ adapter: node({ mode: 'standalone' }),
208
+ });
209
+ ```
210
+
211
+ ### Hybrid Mode
212
+
213
+ Mix SSG and SSR on a per-page basis. Most pages are static; specific routes opt
214
+ into server rendering.
215
+
216
+ ```javascript
217
+ // astro.config.mjs
218
+ export default defineConfig({
219
+ output: 'hybrid',
220
+ adapter: node({ mode: 'standalone' }),
221
+ });
222
+ ```
223
+
224
+ ```astro
225
+ ---
226
+ // src/pages/dashboard.astro — this page is server-rendered
227
+ export const prerender = false;
228
+
229
+ // src/pages/about.astro — this page is statically generated (hybrid default)
230
+ export const prerender = true;
231
+ ---
232
+ ```
233
+
234
+ Use hybrid mode when: most content is static but a few routes need auth or
235
+ live data. Do not make everything `output: 'server'` — you lose the performance
236
+ benefits of static generation.
237
+
238
+ ## Image Optimization
239
+
240
+ Use the built-in `<Image>` and `<Picture>` components. Never use raw `<img>`
241
+ for local assets — you lose automatic optimization.
242
+
243
+ ```astro
244
+ ---
245
+ import { Image, Picture } from 'astro:assets';
246
+ import heroImage from '../assets/hero.png';
247
+ ---
248
+
249
+ <!-- Optimized single image -->
250
+ <Image
251
+ src={heroImage}
252
+ alt="Hero illustration"
253
+ width={800}
254
+ height={600}
255
+ format="webp"
256
+ quality={80}
257
+ />
258
+
259
+ <!-- Responsive with multiple formats -->
260
+ <Picture
261
+ src={heroImage}
262
+ formats={['avif', 'webp']}
263
+ alt="Hero illustration"
264
+ widths={[400, 800, 1200]}
265
+ sizes="(max-width: 800px) 100vw, 800px"
266
+ />
267
+ ```
268
+
269
+ Rules:
270
+
271
+ - Always provide `alt` — empty string is acceptable only for decorative images
272
+ - Prefer `avif` + `webp` fallback for best compression
273
+ - Use `widths` + `sizes` on above-the-fold images to serve the right size per
274
+ viewport
275
+ - Remote images require explicit `width` and `height` to prevent layout shift
276
+
277
+ ## Project Structure
278
+
279
+ ```text
280
+ src/
281
+ assets/ — images and static assets processed by Astro
282
+ components/ — .astro components (and framework islands)
283
+ content/
284
+ blog/ — .md and .mdx files
285
+ config.ts — collection schemas
286
+ layouts/ — page shell layouts
287
+ pages/ — file-based routing; every file is a route
288
+ styles/ — global CSS
289
+ astro.config.mjs
290
+ tsconfig.json
291
+ ```
292
+
293
+ Colocation rule: put framework island components (`.tsx`, `.vue`) in
294
+ `src/components/`. Do not scatter them in `src/pages/`.
295
+
296
+ ## TypeScript Conventions
297
+
298
+ ```json
299
+ // tsconfig.json — use the strict Astro preset
300
+ {
301
+ "extends": "astro/tsconfigs/strict"
302
+ }
303
+ ```
304
+
305
+ ```astro
306
+ ---
307
+ // Type props explicitly in the frontmatter
308
+ interface Props {
309
+ title: string;
310
+ description?: string;
311
+ tags: string[];
312
+ }
313
+
314
+ const { title, description = '', tags } = Astro.props;
315
+ ---
316
+ ```
317
+
318
+ Astro infers prop types from `interface Props` automatically. Do not use `any`.