javi-forge 0.1.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 (500) hide show
  1. package/.gitignore.template +105 -0
  2. package/.releaserc +44 -0
  3. package/README.md +45 -0
  4. package/ai-config/.skillignore +15 -0
  5. package/ai-config/AUTO_INVOKE.md +300 -0
  6. package/ai-config/agents/_TEMPLATE.md +93 -0
  7. package/ai-config/agents/business/api-designer.md +1657 -0
  8. package/ai-config/agents/business/business-analyst.md +1331 -0
  9. package/ai-config/agents/business/product-strategist.md +206 -0
  10. package/ai-config/agents/business/project-manager.md +178 -0
  11. package/ai-config/agents/business/requirements-analyst.md +1277 -0
  12. package/ai-config/agents/business/technical-writer.md +1679 -0
  13. package/ai-config/agents/creative/ux-designer.md +205 -0
  14. package/ai-config/agents/data-ai/ai-engineer.md +487 -0
  15. package/ai-config/agents/data-ai/analytics-engineer.md +953 -0
  16. package/ai-config/agents/data-ai/data-engineer.md +173 -0
  17. package/ai-config/agents/data-ai/data-scientist.md +672 -0
  18. package/ai-config/agents/data-ai/mlops-engineer.md +814 -0
  19. package/ai-config/agents/data-ai/prompt-engineer.md +772 -0
  20. package/ai-config/agents/development/angular-expert.md +620 -0
  21. package/ai-config/agents/development/backend-architect.md +795 -0
  22. package/ai-config/agents/development/database-specialist.md +212 -0
  23. package/ai-config/agents/development/frontend-specialist.md +686 -0
  24. package/ai-config/agents/development/fullstack-engineer.md +668 -0
  25. package/ai-config/agents/development/golang-pro.md +338 -0
  26. package/ai-config/agents/development/java-enterprise.md +400 -0
  27. package/ai-config/agents/development/javascript-pro.md +422 -0
  28. package/ai-config/agents/development/nextjs-pro.md +474 -0
  29. package/ai-config/agents/development/python-pro.md +570 -0
  30. package/ai-config/agents/development/react-pro.md +487 -0
  31. package/ai-config/agents/development/rust-pro.md +246 -0
  32. package/ai-config/agents/development/spring-boot-4-expert.md +326 -0
  33. package/ai-config/agents/development/typescript-pro.md +336 -0
  34. package/ai-config/agents/development/vue-specialist.md +605 -0
  35. package/ai-config/agents/infrastructure/cloud-architect.md +472 -0
  36. package/ai-config/agents/infrastructure/deployment-manager.md +358 -0
  37. package/ai-config/agents/infrastructure/devops-engineer.md +455 -0
  38. package/ai-config/agents/infrastructure/incident-responder.md +519 -0
  39. package/ai-config/agents/infrastructure/kubernetes-expert.md +705 -0
  40. package/ai-config/agents/infrastructure/monitoring-specialist.md +674 -0
  41. package/ai-config/agents/infrastructure/performance-engineer.md +658 -0
  42. package/ai-config/agents/orchestrator.md +241 -0
  43. package/ai-config/agents/quality/accessibility-auditor.md +1204 -0
  44. package/ai-config/agents/quality/code-reviewer-compact.md +123 -0
  45. package/ai-config/agents/quality/code-reviewer.md +363 -0
  46. package/ai-config/agents/quality/dependency-manager.md +743 -0
  47. package/ai-config/agents/quality/e2e-test-specialist.md +1005 -0
  48. package/ai-config/agents/quality/performance-tester.md +1086 -0
  49. package/ai-config/agents/quality/security-auditor.md +133 -0
  50. package/ai-config/agents/quality/test-engineer.md +453 -0
  51. package/ai-config/agents/specialists/api-designer.md +87 -0
  52. package/ai-config/agents/specialists/backend-architect.md +73 -0
  53. package/ai-config/agents/specialists/code-reviewer.md +77 -0
  54. package/ai-config/agents/specialists/db-optimizer.md +75 -0
  55. package/ai-config/agents/specialists/devops-engineer.md +83 -0
  56. package/ai-config/agents/specialists/documentation-writer.md +78 -0
  57. package/ai-config/agents/specialists/frontend-developer.md +75 -0
  58. package/ai-config/agents/specialists/performance-analyst.md +82 -0
  59. package/ai-config/agents/specialists/refactor-specialist.md +74 -0
  60. package/ai-config/agents/specialists/security-auditor.md +74 -0
  61. package/ai-config/agents/specialists/test-engineer.md +81 -0
  62. package/ai-config/agents/specialists/ux-consultant.md +76 -0
  63. package/ai-config/agents/specialized/agent-generator.md +1190 -0
  64. package/ai-config/agents/specialized/blockchain-developer.md +149 -0
  65. package/ai-config/agents/specialized/code-migrator.md +892 -0
  66. package/ai-config/agents/specialized/context-manager.md +978 -0
  67. package/ai-config/agents/specialized/documentation-writer.md +1078 -0
  68. package/ai-config/agents/specialized/ecommerce-expert.md +1756 -0
  69. package/ai-config/agents/specialized/embedded-engineer.md +1714 -0
  70. package/ai-config/agents/specialized/error-detective.md +1034 -0
  71. package/ai-config/agents/specialized/fintech-specialist.md +1659 -0
  72. package/ai-config/agents/specialized/freelance-project-planner-v2.md +1988 -0
  73. package/ai-config/agents/specialized/freelance-project-planner-v3.md +2136 -0
  74. package/ai-config/agents/specialized/freelance-project-planner-v4.md +4503 -0
  75. package/ai-config/agents/specialized/freelance-project-planner.md +722 -0
  76. package/ai-config/agents/specialized/game-developer.md +1963 -0
  77. package/ai-config/agents/specialized/healthcare-dev.md +1620 -0
  78. package/ai-config/agents/specialized/mobile-developer.md +188 -0
  79. package/ai-config/agents/specialized/parallel-plan-executor.md +506 -0
  80. package/ai-config/agents/specialized/plan-executor.md +485 -0
  81. package/ai-config/agents/specialized/solo-dev-planner-modular/00-INDEX.md +485 -0
  82. package/ai-config/agents/specialized/solo-dev-planner-modular/01-CORE.md +3493 -0
  83. package/ai-config/agents/specialized/solo-dev-planner-modular/02-SELF-CORRECTION.md +778 -0
  84. package/ai-config/agents/specialized/solo-dev-planner-modular/03-PROGRESSIVE-SETUP.md +918 -0
  85. package/ai-config/agents/specialized/solo-dev-planner-modular/04-DEPLOYMENT.md +1537 -0
  86. package/ai-config/agents/specialized/solo-dev-planner-modular/05-TESTING.md +2633 -0
  87. package/ai-config/agents/specialized/solo-dev-planner-modular/06-OPERATIONS.md +5610 -0
  88. package/ai-config/agents/specialized/solo-dev-planner-modular/INSTALL.md +335 -0
  89. package/ai-config/agents/specialized/solo-dev-planner-modular/QUICK-REFERENCE.txt +215 -0
  90. package/ai-config/agents/specialized/solo-dev-planner-modular/README.md +260 -0
  91. package/ai-config/agents/specialized/solo-dev-planner-modular/START-HERE.md +379 -0
  92. package/ai-config/agents/specialized/solo-dev-planner-modular/WORKFLOW-DIAGRAM.md +355 -0
  93. package/ai-config/agents/specialized/solo-dev-planner-modular/solo-dev-planner.md +279 -0
  94. package/ai-config/agents/specialized/template-writer.md +347 -0
  95. package/ai-config/agents/specialized/test-runner.md +99 -0
  96. package/ai-config/agents/specialized/vibekanban-smart-worker.md +244 -0
  97. package/ai-config/agents/specialized/wave-executor.md +138 -0
  98. package/ai-config/agents/specialized/workflow-optimizer.md +1114 -0
  99. package/ai-config/commands/git/changelog.md +32 -0
  100. package/ai-config/commands/git/ci-local.md +70 -0
  101. package/ai-config/commands/git/commit.md +35 -0
  102. package/ai-config/commands/git/fix-issue.md +23 -0
  103. package/ai-config/commands/git/pr-create.md +42 -0
  104. package/ai-config/commands/git/pr-review.md +50 -0
  105. package/ai-config/commands/git/worktree.md +39 -0
  106. package/ai-config/commands/refactoring/cleanup.md +24 -0
  107. package/ai-config/commands/refactoring/dead-code.md +40 -0
  108. package/ai-config/commands/refactoring/extract.md +31 -0
  109. package/ai-config/commands/testing/e2e.md +30 -0
  110. package/ai-config/commands/testing/tdd.md +36 -0
  111. package/ai-config/commands/testing/test-coverage.md +30 -0
  112. package/ai-config/commands/testing/test-fix.md +24 -0
  113. package/ai-config/commands/workflow/generate-agents-md.md +85 -0
  114. package/ai-config/commands/workflow/planning.md +47 -0
  115. package/ai-config/commands/workflows/compound.md +89 -0
  116. package/ai-config/commands/workflows/plan.md +77 -0
  117. package/ai-config/commands/workflows/review.md +78 -0
  118. package/ai-config/commands/workflows/work.md +75 -0
  119. package/ai-config/config.yaml +18 -0
  120. package/ai-config/hooks/_TEMPLATE.md +96 -0
  121. package/ai-config/hooks/block-dangerous-commands.md +75 -0
  122. package/ai-config/hooks/commit-guard.md +90 -0
  123. package/ai-config/hooks/context-loader.md +73 -0
  124. package/ai-config/hooks/improve-prompt.md +91 -0
  125. package/ai-config/hooks/learning-log.md +72 -0
  126. package/ai-config/hooks/model-router.md +86 -0
  127. package/ai-config/hooks/secret-scanner.md +64 -0
  128. package/ai-config/hooks/skill-validator.md +102 -0
  129. package/ai-config/hooks/task-artifact.md +114 -0
  130. package/ai-config/hooks/validate-workflow.md +100 -0
  131. package/ai-config/prompts/base.md +71 -0
  132. package/ai-config/prompts/modes/debug.md +34 -0
  133. package/ai-config/prompts/modes/deploy.md +40 -0
  134. package/ai-config/prompts/modes/research.md +32 -0
  135. package/ai-config/prompts/modes/review.md +33 -0
  136. package/ai-config/prompts/review-policy.md +79 -0
  137. package/ai-config/skills/_TEMPLATE.md +157 -0
  138. package/ai-config/skills/backend/api-gateway/SKILL.md +254 -0
  139. package/ai-config/skills/backend/bff-concepts/SKILL.md +239 -0
  140. package/ai-config/skills/backend/bff-spring/SKILL.md +364 -0
  141. package/ai-config/skills/backend/chi-router/SKILL.md +396 -0
  142. package/ai-config/skills/backend/error-handling/SKILL.md +255 -0
  143. package/ai-config/skills/backend/exceptions-spring/SKILL.md +323 -0
  144. package/ai-config/skills/backend/fastapi/SKILL.md +302 -0
  145. package/ai-config/skills/backend/gateway-spring/SKILL.md +390 -0
  146. package/ai-config/skills/backend/go-backend/SKILL.md +457 -0
  147. package/ai-config/skills/backend/gradle-multimodule/SKILL.md +274 -0
  148. package/ai-config/skills/backend/graphql-concepts/SKILL.md +352 -0
  149. package/ai-config/skills/backend/graphql-spring/SKILL.md +398 -0
  150. package/ai-config/skills/backend/grpc-concepts/SKILL.md +283 -0
  151. package/ai-config/skills/backend/grpc-spring/SKILL.md +445 -0
  152. package/ai-config/skills/backend/jwt-auth/SKILL.md +412 -0
  153. package/ai-config/skills/backend/notifications-concepts/SKILL.md +259 -0
  154. package/ai-config/skills/backend/recommendations-concepts/SKILL.md +261 -0
  155. package/ai-config/skills/backend/search-concepts/SKILL.md +263 -0
  156. package/ai-config/skills/backend/search-spring/SKILL.md +375 -0
  157. package/ai-config/skills/backend/spring-boot-4/SKILL.md +172 -0
  158. package/ai-config/skills/backend/websockets/SKILL.md +532 -0
  159. package/ai-config/skills/data-ai/ai-ml/SKILL.md +423 -0
  160. package/ai-config/skills/data-ai/analytics-concepts/SKILL.md +195 -0
  161. package/ai-config/skills/data-ai/analytics-spring/SKILL.md +340 -0
  162. package/ai-config/skills/data-ai/duckdb-analytics/SKILL.md +440 -0
  163. package/ai-config/skills/data-ai/langchain/SKILL.md +238 -0
  164. package/ai-config/skills/data-ai/mlflow/SKILL.md +302 -0
  165. package/ai-config/skills/data-ai/onnx-inference/SKILL.md +290 -0
  166. package/ai-config/skills/data-ai/powerbi/SKILL.md +352 -0
  167. package/ai-config/skills/data-ai/pytorch/SKILL.md +274 -0
  168. package/ai-config/skills/data-ai/scikit-learn/SKILL.md +321 -0
  169. package/ai-config/skills/data-ai/vector-db/SKILL.md +301 -0
  170. package/ai-config/skills/database/graph-databases/SKILL.md +218 -0
  171. package/ai-config/skills/database/graph-spring/SKILL.md +361 -0
  172. package/ai-config/skills/database/pgx-postgres/SKILL.md +512 -0
  173. package/ai-config/skills/database/redis-cache/SKILL.md +343 -0
  174. package/ai-config/skills/database/sqlite-embedded/SKILL.md +388 -0
  175. package/ai-config/skills/database/timescaledb/SKILL.md +320 -0
  176. package/ai-config/skills/docs/api-documentation/SKILL.md +293 -0
  177. package/ai-config/skills/docs/docs-spring/SKILL.md +377 -0
  178. package/ai-config/skills/docs/mustache-templates/SKILL.md +190 -0
  179. package/ai-config/skills/docs/technical-docs/SKILL.md +447 -0
  180. package/ai-config/skills/frontend/astro-ssr/SKILL.md +441 -0
  181. package/ai-config/skills/frontend/frontend-design/SKILL.md +54 -0
  182. package/ai-config/skills/frontend/frontend-web/SKILL.md +368 -0
  183. package/ai-config/skills/frontend/mantine-ui/SKILL.md +396 -0
  184. package/ai-config/skills/frontend/tanstack-query/SKILL.md +439 -0
  185. package/ai-config/skills/frontend/zod-validation/SKILL.md +417 -0
  186. package/ai-config/skills/frontend/zustand-state/SKILL.md +350 -0
  187. package/ai-config/skills/infrastructure/chaos-engineering/SKILL.md +244 -0
  188. package/ai-config/skills/infrastructure/chaos-spring/SKILL.md +378 -0
  189. package/ai-config/skills/infrastructure/devops-infra/SKILL.md +435 -0
  190. package/ai-config/skills/infrastructure/docker-containers/SKILL.md +420 -0
  191. package/ai-config/skills/infrastructure/kubernetes/SKILL.md +456 -0
  192. package/ai-config/skills/infrastructure/opentelemetry/SKILL.md +546 -0
  193. package/ai-config/skills/infrastructure/traefik-proxy/SKILL.md +474 -0
  194. package/ai-config/skills/infrastructure/woodpecker-ci/SKILL.md +315 -0
  195. package/ai-config/skills/mobile/ionic-capacitor/SKILL.md +504 -0
  196. package/ai-config/skills/mobile/mobile-ionic/SKILL.md +448 -0
  197. package/ai-config/skills/prompt-improver/SKILL.md +125 -0
  198. package/ai-config/skills/quality/ghagga-review/SKILL.md +216 -0
  199. package/ai-config/skills/references/hooks-patterns/SKILL.md +238 -0
  200. package/ai-config/skills/references/mcp-servers/SKILL.md +275 -0
  201. package/ai-config/skills/references/plugins-reference/SKILL.md +110 -0
  202. package/ai-config/skills/references/skills-reference/SKILL.md +420 -0
  203. package/ai-config/skills/references/subagent-templates/SKILL.md +193 -0
  204. package/ai-config/skills/systems-iot/modbus-protocol/SKILL.md +410 -0
  205. package/ai-config/skills/systems-iot/mqtt-rumqttc/SKILL.md +408 -0
  206. package/ai-config/skills/systems-iot/rust-systems/SKILL.md +386 -0
  207. package/ai-config/skills/systems-iot/tokio-async/SKILL.md +324 -0
  208. package/ai-config/skills/testing/playwright-e2e/SKILL.md +289 -0
  209. package/ai-config/skills/testing/testcontainers/SKILL.md +299 -0
  210. package/ai-config/skills/testing/vitest-testing/SKILL.md +381 -0
  211. package/ai-config/skills/workflow/ci-local-guide/SKILL.md +118 -0
  212. package/ai-config/skills/workflow/claude-automation-recommender/SKILL.md +299 -0
  213. package/ai-config/skills/workflow/claude-md-improver/SKILL.md +158 -0
  214. package/ai-config/skills/workflow/finishing-a-development-branch/SKILL.md +117 -0
  215. package/ai-config/skills/workflow/git-github/SKILL.md +334 -0
  216. package/ai-config/skills/workflow/git-github/references/examples.md +160 -0
  217. package/ai-config/skills/workflow/git-workflow/SKILL.md +214 -0
  218. package/ai-config/skills/workflow/ide-plugins/SKILL.md +277 -0
  219. package/ai-config/skills/workflow/ide-plugins-intellij/SKILL.md +401 -0
  220. package/ai-config/skills/workflow/obsidian-brain-workflow/SKILL.md +199 -0
  221. package/ai-config/skills/workflow/using-git-worktrees/SKILL.md +100 -0
  222. package/ai-config/skills/workflow/verification-before-completion/SKILL.md +73 -0
  223. package/ai-config/skills/workflow/wave-workflow/SKILL.md +178 -0
  224. package/ci-local/README.md +170 -0
  225. package/ci-local/ci-local.sh +297 -0
  226. package/ci-local/hooks/commit-msg +74 -0
  227. package/ci-local/hooks/pre-commit +162 -0
  228. package/ci-local/hooks/pre-push +41 -0
  229. package/ci-local/install.sh +49 -0
  230. package/ci-local/semgrep.yml +214 -0
  231. package/dist/commands/analyze.d.ts +9 -0
  232. package/dist/commands/analyze.d.ts.map +1 -0
  233. package/dist/commands/analyze.js +55 -0
  234. package/dist/commands/analyze.js.map +1 -0
  235. package/dist/commands/analyze.test.d.ts +2 -0
  236. package/dist/commands/analyze.test.d.ts.map +1 -0
  237. package/dist/commands/analyze.test.js +145 -0
  238. package/dist/commands/analyze.test.js.map +1 -0
  239. package/dist/commands/doctor.d.ts +7 -0
  240. package/dist/commands/doctor.d.ts.map +1 -0
  241. package/dist/commands/doctor.js +158 -0
  242. package/dist/commands/doctor.js.map +1 -0
  243. package/dist/commands/doctor.test.d.ts +2 -0
  244. package/dist/commands/doctor.test.d.ts.map +1 -0
  245. package/dist/commands/doctor.test.js +200 -0
  246. package/dist/commands/doctor.test.js.map +1 -0
  247. package/dist/commands/init.d.ts +9 -0
  248. package/dist/commands/init.d.ts.map +1 -0
  249. package/dist/commands/init.js +283 -0
  250. package/dist/commands/init.js.map +1 -0
  251. package/dist/commands/init.test.d.ts +2 -0
  252. package/dist/commands/init.test.d.ts.map +1 -0
  253. package/dist/commands/init.test.js +271 -0
  254. package/dist/commands/init.test.js.map +1 -0
  255. package/dist/commands/sync.d.ts +8 -0
  256. package/dist/commands/sync.d.ts.map +1 -0
  257. package/dist/commands/sync.js +201 -0
  258. package/dist/commands/sync.js.map +1 -0
  259. package/dist/constants.d.ts +21 -0
  260. package/dist/constants.d.ts.map +1 -0
  261. package/dist/constants.js +57 -0
  262. package/dist/constants.js.map +1 -0
  263. package/dist/e2e/aggressive.e2e.test.d.ts +2 -0
  264. package/dist/e2e/aggressive.e2e.test.d.ts.map +1 -0
  265. package/dist/e2e/aggressive.e2e.test.js +350 -0
  266. package/dist/e2e/aggressive.e2e.test.js.map +1 -0
  267. package/dist/e2e/commands.e2e.test.d.ts +2 -0
  268. package/dist/e2e/commands.e2e.test.d.ts.map +1 -0
  269. package/dist/e2e/commands.e2e.test.js +213 -0
  270. package/dist/e2e/commands.e2e.test.js.map +1 -0
  271. package/dist/index.d.ts +3 -0
  272. package/dist/index.d.ts.map +1 -0
  273. package/dist/index.js +82 -0
  274. package/dist/index.js.map +1 -0
  275. package/dist/lib/common.d.ts +17 -0
  276. package/dist/lib/common.d.ts.map +1 -0
  277. package/dist/lib/common.js +111 -0
  278. package/dist/lib/common.js.map +1 -0
  279. package/dist/lib/common.test.d.ts +2 -0
  280. package/dist/lib/common.test.d.ts.map +1 -0
  281. package/dist/lib/common.test.js +316 -0
  282. package/dist/lib/common.test.js.map +1 -0
  283. package/dist/lib/frontmatter.d.ts +18 -0
  284. package/dist/lib/frontmatter.d.ts.map +1 -0
  285. package/dist/lib/frontmatter.js +61 -0
  286. package/dist/lib/frontmatter.js.map +1 -0
  287. package/dist/lib/frontmatter.test.d.ts +2 -0
  288. package/dist/lib/frontmatter.test.d.ts.map +1 -0
  289. package/dist/lib/frontmatter.test.js +257 -0
  290. package/dist/lib/frontmatter.test.js.map +1 -0
  291. package/dist/lib/template.d.ts +24 -0
  292. package/dist/lib/template.d.ts.map +1 -0
  293. package/dist/lib/template.js +78 -0
  294. package/dist/lib/template.js.map +1 -0
  295. package/dist/lib/template.test.d.ts +2 -0
  296. package/dist/lib/template.test.d.ts.map +1 -0
  297. package/dist/lib/template.test.js +201 -0
  298. package/dist/lib/template.test.js.map +1 -0
  299. package/dist/types/index.d.ts +48 -0
  300. package/dist/types/index.d.ts.map +1 -0
  301. package/dist/types/index.js +2 -0
  302. package/dist/types/index.js.map +1 -0
  303. package/dist/ui/AnalyzeUI.d.ts +7 -0
  304. package/dist/ui/AnalyzeUI.d.ts.map +1 -0
  305. package/dist/ui/AnalyzeUI.js +100 -0
  306. package/dist/ui/AnalyzeUI.js.map +1 -0
  307. package/dist/ui/App.d.ts +13 -0
  308. package/dist/ui/App.d.ts.map +1 -0
  309. package/dist/ui/App.js +100 -0
  310. package/dist/ui/App.js.map +1 -0
  311. package/dist/ui/CIContext.d.ts +9 -0
  312. package/dist/ui/CIContext.d.ts.map +1 -0
  313. package/dist/ui/CIContext.js +9 -0
  314. package/dist/ui/CIContext.js.map +1 -0
  315. package/dist/ui/CISelector.d.ts +8 -0
  316. package/dist/ui/CISelector.d.ts.map +1 -0
  317. package/dist/ui/CISelector.js +45 -0
  318. package/dist/ui/CISelector.js.map +1 -0
  319. package/dist/ui/Doctor.d.ts +3 -0
  320. package/dist/ui/Doctor.d.ts.map +1 -0
  321. package/dist/ui/Doctor.js +89 -0
  322. package/dist/ui/Doctor.js.map +1 -0
  323. package/dist/ui/Header.d.ts +8 -0
  324. package/dist/ui/Header.d.ts.map +1 -0
  325. package/dist/ui/Header.js +30 -0
  326. package/dist/ui/Header.js.map +1 -0
  327. package/dist/ui/MemorySelector.d.ts +8 -0
  328. package/dist/ui/MemorySelector.d.ts.map +1 -0
  329. package/dist/ui/MemorySelector.js +46 -0
  330. package/dist/ui/MemorySelector.js.map +1 -0
  331. package/dist/ui/NameInput.d.ts +8 -0
  332. package/dist/ui/NameInput.d.ts.map +1 -0
  333. package/dist/ui/NameInput.js +69 -0
  334. package/dist/ui/NameInput.js.map +1 -0
  335. package/dist/ui/OptionSelector.d.ts +12 -0
  336. package/dist/ui/OptionSelector.d.ts.map +1 -0
  337. package/dist/ui/OptionSelector.js +69 -0
  338. package/dist/ui/OptionSelector.js.map +1 -0
  339. package/dist/ui/Progress.d.ts +11 -0
  340. package/dist/ui/Progress.d.ts.map +1 -0
  341. package/dist/ui/Progress.js +58 -0
  342. package/dist/ui/Progress.js.map +1 -0
  343. package/dist/ui/StackSelector.d.ts +9 -0
  344. package/dist/ui/StackSelector.d.ts.map +1 -0
  345. package/dist/ui/StackSelector.js +65 -0
  346. package/dist/ui/StackSelector.js.map +1 -0
  347. package/dist/ui/Summary.d.ts +12 -0
  348. package/dist/ui/Summary.d.ts.map +1 -0
  349. package/dist/ui/Summary.js +114 -0
  350. package/dist/ui/Summary.js.map +1 -0
  351. package/dist/ui/SyncUI.d.ts +10 -0
  352. package/dist/ui/SyncUI.d.ts.map +1 -0
  353. package/dist/ui/SyncUI.js +64 -0
  354. package/dist/ui/SyncUI.js.map +1 -0
  355. package/dist/ui/Welcome.d.ts +7 -0
  356. package/dist/ui/Welcome.d.ts.map +1 -0
  357. package/dist/ui/Welcome.js +45 -0
  358. package/dist/ui/Welcome.js.map +1 -0
  359. package/dist/ui/theme.d.ts +10 -0
  360. package/dist/ui/theme.d.ts.map +1 -0
  361. package/dist/ui/theme.js +9 -0
  362. package/dist/ui/theme.js.map +1 -0
  363. package/modules/engram/.gitignore-snippet.txt +6 -0
  364. package/modules/engram/.mcp-config-snippet.json +11 -0
  365. package/modules/engram/README.md +146 -0
  366. package/modules/engram/install-engram.sh +216 -0
  367. package/modules/ghagga/.env.example +43 -0
  368. package/modules/ghagga/README.md +153 -0
  369. package/modules/ghagga/docker-compose.yml +80 -0
  370. package/modules/ghagga/setup-ghagga.sh +139 -0
  371. package/modules/memory-simple/.project/NOTES.md +22 -0
  372. package/modules/memory-simple/README.md +23 -0
  373. package/modules/obsidian-brain/.obsidian/app.json +23 -0
  374. package/modules/obsidian-brain/.obsidian/appearance.json +5 -0
  375. package/modules/obsidian-brain/.obsidian/bookmarks.json +34 -0
  376. package/modules/obsidian-brain/.obsidian/community-plugins.json +1 -0
  377. package/modules/obsidian-brain/.obsidian/core-plugins-migration.json +21 -0
  378. package/modules/obsidian-brain/.obsidian/core-plugins.json +18 -0
  379. package/modules/obsidian-brain/.obsidian/daily-notes.json +5 -0
  380. package/modules/obsidian-brain/.obsidian/graph.json +37 -0
  381. package/modules/obsidian-brain/.obsidian/hotkeys.json +14 -0
  382. package/modules/obsidian-brain/.obsidian/plugins/dataview/data.json +25 -0
  383. package/modules/obsidian-brain/.obsidian/plugins/obsidian-kanban/data.json +29 -0
  384. package/modules/obsidian-brain/.obsidian/plugins/templater-obsidian/data.json +18 -0
  385. package/modules/obsidian-brain/.obsidian/snippets/project-memory.css +71 -0
  386. package/modules/obsidian-brain/.obsidian-gitignore-snippet.txt +8 -0
  387. package/modules/obsidian-brain/.project/Attachments/.gitkeep +0 -0
  388. package/modules/obsidian-brain/.project/Memory/BLOCKERS.md +78 -0
  389. package/modules/obsidian-brain/.project/Memory/CONTEXT.md +102 -0
  390. package/modules/obsidian-brain/.project/Memory/DASHBOARD.md +73 -0
  391. package/modules/obsidian-brain/.project/Memory/DECISIONS.md +87 -0
  392. package/modules/obsidian-brain/.project/Memory/KANBAN.md +15 -0
  393. package/modules/obsidian-brain/.project/Memory/README.md +61 -0
  394. package/modules/obsidian-brain/.project/Memory/WAVES.md +78 -0
  395. package/modules/obsidian-brain/.project/Sessions/TEMPLATE.md +99 -0
  396. package/modules/obsidian-brain/.project/Templates/ADR.md +33 -0
  397. package/modules/obsidian-brain/.project/Templates/Blocker.md +21 -0
  398. package/modules/obsidian-brain/.project/Templates/Session.md +88 -0
  399. package/modules/obsidian-brain/README.md +268 -0
  400. package/modules/obsidian-brain/new-wave.sh +182 -0
  401. package/package.json +51 -0
  402. package/schemas/agent.schema.json +34 -0
  403. package/schemas/ai-config.schema.json +28 -0
  404. package/schemas/skill.schema.json +44 -0
  405. package/src/commands/analyze.test.ts +145 -0
  406. package/src/commands/analyze.ts +69 -0
  407. package/src/commands/doctor.test.ts +208 -0
  408. package/src/commands/doctor.ts +163 -0
  409. package/src/commands/init.test.ts +298 -0
  410. package/src/commands/init.ts +285 -0
  411. package/src/constants.ts +69 -0
  412. package/src/e2e/aggressive.e2e.test.ts +557 -0
  413. package/src/e2e/commands.e2e.test.ts +298 -0
  414. package/src/index.tsx +106 -0
  415. package/src/lib/common.test.ts +318 -0
  416. package/src/lib/common.ts +127 -0
  417. package/src/lib/frontmatter.test.ts +291 -0
  418. package/src/lib/frontmatter.ts +77 -0
  419. package/src/lib/template.test.ts +226 -0
  420. package/src/lib/template.ts +99 -0
  421. package/src/types/index.ts +53 -0
  422. package/src/ui/AnalyzeUI.tsx +133 -0
  423. package/src/ui/App.tsx +175 -0
  424. package/src/ui/CIContext.tsx +25 -0
  425. package/src/ui/CISelector.tsx +72 -0
  426. package/src/ui/Doctor.tsx +122 -0
  427. package/src/ui/Header.tsx +48 -0
  428. package/src/ui/MemorySelector.tsx +73 -0
  429. package/src/ui/NameInput.tsx +82 -0
  430. package/src/ui/OptionSelector.tsx +100 -0
  431. package/src/ui/Progress.tsx +88 -0
  432. package/src/ui/StackSelector.tsx +101 -0
  433. package/src/ui/Summary.tsx +134 -0
  434. package/src/ui/Welcome.tsx +54 -0
  435. package/src/ui/theme.ts +10 -0
  436. package/stryker.config.json +19 -0
  437. package/tasks/_TEMPLATE/files-edited.md +3 -0
  438. package/tasks/_TEMPLATE/plan.md +3 -0
  439. package/tasks/_TEMPLATE/research.md +3 -0
  440. package/tasks/_TEMPLATE/verification.md +5 -0
  441. package/templates/common/dependabot/cargo.yml +11 -0
  442. package/templates/common/dependabot/github-actions.yml +16 -0
  443. package/templates/common/dependabot/gomod.yml +15 -0
  444. package/templates/common/dependabot/gradle.yml +15 -0
  445. package/templates/common/dependabot/header.yml +3 -0
  446. package/templates/common/dependabot/maven.yml +15 -0
  447. package/templates/common/dependabot/npm.yml +20 -0
  448. package/templates/common/dependabot/pip.yml +11 -0
  449. package/templates/dependabot.yml +162 -0
  450. package/templates/github/ci-go.yml +41 -0
  451. package/templates/github/ci-java.yml +45 -0
  452. package/templates/github/ci-monorepo.yml +150 -0
  453. package/templates/github/ci-node.yml +42 -0
  454. package/templates/github/ci-python.yml +42 -0
  455. package/templates/github/ci-rust.yml +42 -0
  456. package/templates/github/dependabot-automerge.yml +40 -0
  457. package/templates/gitlab/gitlab-ci-go.yml +88 -0
  458. package/templates/gitlab/gitlab-ci-java.yml +79 -0
  459. package/templates/gitlab/gitlab-ci-monorepo.yml +126 -0
  460. package/templates/gitlab/gitlab-ci-node.yml +63 -0
  461. package/templates/gitlab/gitlab-ci-python.yml +147 -0
  462. package/templates/gitlab/gitlab-ci-rust.yml +67 -0
  463. package/templates/global/claude-settings.json +98 -0
  464. package/templates/global/codex-config.toml +8 -0
  465. package/templates/global/copilot-instructions/base-rules.instructions.md +13 -0
  466. package/templates/global/copilot-instructions/sdd-orchestrator.instructions.md +37 -0
  467. package/templates/global/gemini-commands/cleanup.toml +20 -0
  468. package/templates/global/gemini-commands/commit.toml +15 -0
  469. package/templates/global/gemini-commands/dead-code.toml +22 -0
  470. package/templates/global/gemini-commands/plan.toml +30 -0
  471. package/templates/global/gemini-commands/review.toml +17 -0
  472. package/templates/global/gemini-commands/sdd-apply.toml +22 -0
  473. package/templates/global/gemini-commands/sdd-ff.toml +14 -0
  474. package/templates/global/gemini-commands/sdd-new.toml +21 -0
  475. package/templates/global/gemini-commands/sdd-verify.toml +21 -0
  476. package/templates/global/gemini-commands/tdd.toml +26 -0
  477. package/templates/global/gemini-settings.json +8 -0
  478. package/templates/global/opencode-config.json +44 -0
  479. package/templates/global/sdd-instructions.md +47 -0
  480. package/templates/global/sdd-orchestrator-claude.md +46 -0
  481. package/templates/global/sdd-orchestrator-copilot.md +34 -0
  482. package/templates/renovate.json +69 -0
  483. package/templates/woodpecker/monorepo/backend.yml +34 -0
  484. package/templates/woodpecker/monorepo/frontend.yml +34 -0
  485. package/templates/woodpecker/monorepo/summary.yml +25 -0
  486. package/templates/woodpecker/woodpecker-go.yml +51 -0
  487. package/templates/woodpecker/woodpecker-java.yml +67 -0
  488. package/templates/woodpecker/woodpecker-node.yml +47 -0
  489. package/templates/woodpecker/woodpecker-python.yml +108 -0
  490. package/templates/woodpecker/woodpecker-rust.yml +57 -0
  491. package/tsconfig.json +19 -0
  492. package/vitest.config.ts +16 -0
  493. package/workflows/reusable-build-go.yml +111 -0
  494. package/workflows/reusable-build-java.yml +120 -0
  495. package/workflows/reusable-build-node.yml +145 -0
  496. package/workflows/reusable-build-python.yml +159 -0
  497. package/workflows/reusable-build-rust.yml +135 -0
  498. package/workflows/reusable-docker.yml +120 -0
  499. package/workflows/reusable-ghagga-review.yml +165 -0
  500. package/workflows/reusable-release.yml +91 -0
@@ -0,0 +1,239 @@
1
+ ---
2
+ name: bff-concepts
3
+ description: >
4
+ Backend for Frontend pattern. Client-specific APIs, response tailoring, aggregation.
5
+ Trigger: BFF, backend for frontend, aggregation, client-specific, mobile API
6
+ tools:
7
+ - Read
8
+ - Write
9
+ - Edit
10
+ - Grep
11
+ metadata:
12
+ author: apigen-team
13
+ version: "1.0"
14
+ tags: [bff, architecture, api-design, microservices]
15
+ scope: ["**/bff/**"]
16
+ ---
17
+
18
+ # Backend for Frontend (BFF) Pattern
19
+
20
+ ## Core Concept
21
+
22
+ ```
23
+ Traditional API:
24
+ ┌─────────────────────────────────────────┐
25
+ │ Single Generic API │
26
+ │ (serves Web, Mobile, TV, Partners) │
27
+ └─────────────────────────────────────────┘
28
+ ↓ ↓ ↓
29
+ [Web] [Mobile] [TV]
30
+ (over-fetching + under-fetching)
31
+
32
+ BFF Pattern:
33
+ ┌───────────┐ ┌───────────┐ ┌───────────┐
34
+ │ Web BFF │ │Mobile BFF │ │ TV BFF │
35
+ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘
36
+ ↓ ↓ ↓
37
+ ┌─────────────────────────────────────────┐
38
+ │ Backend Microservices │
39
+ └─────────────────────────────────────────┘
40
+ ```
41
+
42
+ ## Client Types
43
+
44
+ ### Web BFF
45
+ ```
46
+ Characteristics:
47
+ - Full data payloads (fast connections)
48
+ - Rich interaction capabilities
49
+ - SEO requirements (SSR data)
50
+ - Complex filtering/sorting UI
51
+
52
+ Typical operations:
53
+ - Large paginated lists
54
+ - Real-time updates (WebSocket)
55
+ - Complex search queries
56
+ - File uploads
57
+ ```
58
+
59
+ ### Mobile BFF
60
+ ```
61
+ Characteristics:
62
+ - Bandwidth optimization
63
+ - Battery conservation
64
+ - Offline support (sync)
65
+ - Push notifications
66
+
67
+ Optimizations:
68
+ - Compressed responses
69
+ - Delta sync (only changes)
70
+ - Image CDN URLs (different sizes)
71
+ - Aggressive caching headers
72
+ ```
73
+
74
+ ### IoT / Embedded BFF
75
+ ```
76
+ Characteristics:
77
+ - Minimal payloads
78
+ - Low memory footprint
79
+ - Binary protocols (gRPC/MQTT)
80
+ - Intermittent connectivity
81
+
82
+ Patterns:
83
+ - Batch operations
84
+ - Store-and-forward
85
+ - Heartbeat polling
86
+ ```
87
+
88
+ ## Response Tailoring
89
+
90
+ ### Field Selection
91
+ ```json
92
+ // Web: Full response
93
+ {
94
+ "user": {
95
+ "id": "123",
96
+ "name": "John Doe",
97
+ "email": "john@example.com",
98
+ "avatar": "https://...",
99
+ "bio": "...",
100
+ "preferences": {...},
101
+ "stats": {...}
102
+ }
103
+ }
104
+
105
+ // Mobile: Tailored response
106
+ {
107
+ "user": {
108
+ "id": "123",
109
+ "name": "John Doe",
110
+ "avatar_thumb": "https://.../48x48"
111
+ }
112
+ }
113
+ ```
114
+
115
+ ### Aggregation Strategies
116
+ ```
117
+ Sequential:
118
+ 1. Get user profile
119
+ 2. Get user's orders
120
+ 3. Get recommendations
121
+ 4. Combine and return
122
+
123
+ Parallel:
124
+ 1. Fork: [profile, orders, recommendations]
125
+ 2. Join: Combine results
126
+ 3. Return aggregated response
127
+
128
+ Conditional:
129
+ 1. Get user profile
130
+ 2. IF premium user THEN get recommendations
131
+ 3. Return appropriate response
132
+ ```
133
+
134
+ ## Rate Limiting per Client
135
+
136
+ ```
137
+ Web clients:
138
+ - 1000 req/min (authenticated)
139
+ - 100 req/min (anonymous)
140
+
141
+ Mobile clients:
142
+ - 500 req/min (aggressive caching expected)
143
+
144
+ Partner APIs:
145
+ - Per-contract limits
146
+ - Separate quotas per partner
147
+ ```
148
+
149
+ ## Query Composition
150
+
151
+ ### GraphQL-like Behavior
152
+ ```
153
+ Request:
154
+ GET /bff/dashboard?include=profile,notifications,orders
155
+
156
+ Response:
157
+ {
158
+ "profile": {...},
159
+ "notifications": [...],
160
+ "orders": [...]
161
+ }
162
+
163
+ Backend calls:
164
+ - GET /users/me → profile
165
+ - GET /notifications?limit=5 → notifications
166
+ - GET /orders?status=pending → orders
167
+ ```
168
+
169
+ ### Partial Failure Handling
170
+ ```json
171
+ {
172
+ "profile": {...},
173
+ "notifications": {
174
+ "_error": "Service temporarily unavailable",
175
+ "_fallback": []
176
+ },
177
+ "orders": [...]
178
+ }
179
+ ```
180
+
181
+ ## Caching Strategies
182
+
183
+ ```
184
+ Per-client-type:
185
+ - Web: 5 min cache, ETags
186
+ - Mobile: 30 min cache, stale-while-revalidate
187
+ - IoT: 1 hour cache
188
+
189
+ Per-resource:
190
+ - User profile: 5 min
191
+ - Product catalog: 1 hour
192
+ - Recommendations: 15 min
193
+ ```
194
+
195
+ ## Implementation Patterns
196
+
197
+ ### Request/Response DTOs
198
+ ```
199
+ // Client-specific DTOs
200
+ WebUserResponse:
201
+ - All fields
202
+ - Nested objects
203
+ - Full links
204
+
205
+ MobileUserResponse:
206
+ - Essential fields only
207
+ - IDs instead of nested objects
208
+ - Thumbnail URLs
209
+ ```
210
+
211
+ ### Service Orchestration
212
+ ```
213
+ BFF Controller:
214
+ 1. Parse client context (User-Agent, Accept)
215
+ 2. Determine required data
216
+ 3. Call services (parallel when possible)
217
+ 4. Apply transformations
218
+ 5. Return tailored response
219
+ ```
220
+
221
+ ## Anti-patterns to Avoid
222
+
223
+ ```
224
+ ❌ Business logic in BFF
225
+ → BFF should only orchestrate and transform
226
+
227
+ ❌ Direct database access
228
+ → Always go through services
229
+
230
+ ❌ Shared BFF for different clients
231
+ → Each client type needs its own BFF
232
+
233
+ ❌ Duplicating validation
234
+ → Let backend services handle validation
235
+ ```
236
+
237
+ ## Related Skills
238
+
239
+ - `bff-spring`: Spring Boot BFF implementation
@@ -0,0 +1,364 @@
1
+ ---
2
+ name: bff-spring
3
+ description: >
4
+ Spring Boot BFF implementation. Client detection, response tailoring, service composition.
5
+ Trigger: apigen-bff, BaseBffController, ClientType, TailorForClient, aggregation
6
+ tools:
7
+ - Read
8
+ - Write
9
+ - Edit
10
+ - Bash
11
+ - Grep
12
+ metadata:
13
+ author: apigen-team
14
+ version: "1.0"
15
+ tags: [bff, spring-boot, aggregation, java]
16
+ scope: ["apigen-bff/**"]
17
+ ---
18
+
19
+ # BFF Spring Boot (apigen-bff)
20
+
21
+ ## Configuration
22
+
23
+ ```yaml
24
+ apigen:
25
+ bff:
26
+ enabled: true
27
+
28
+ client-detection:
29
+ header: X-Client-Type
30
+ fallback: WEB
31
+
32
+ rate-limits:
33
+ web:
34
+ requests-per-minute: 1000
35
+ mobile:
36
+ requests-per-minute: 500
37
+ iot:
38
+ requests-per-minute: 100
39
+
40
+ response-tailoring:
41
+ enabled: true
42
+ compress-mobile: true
43
+
44
+ composition:
45
+ timeout: 5s
46
+ parallel-enabled: true
47
+ ```
48
+
49
+ ## Client Type Detection
50
+
51
+ ```java
52
+ public enum ClientType {
53
+ WEB("web"),
54
+ MOBILE_IOS("ios"),
55
+ MOBILE_ANDROID("android"),
56
+ TABLET("tablet"),
57
+ TV("tv"),
58
+ IOT("iot"),
59
+ PARTNER("partner");
60
+
61
+ public boolean isMobile() {
62
+ return this == MOBILE_IOS || this == MOBILE_ANDROID;
63
+ }
64
+
65
+ public boolean requiresCompression() {
66
+ return isMobile() || this == IOT;
67
+ }
68
+ }
69
+ ```
70
+
71
+ ## Annotations
72
+
73
+ ```java
74
+ @Target(ElementType.METHOD)
75
+ @Retention(RetentionPolicy.RUNTIME)
76
+ public @interface BffEndpoint {
77
+ ClientType[] clients() default {};
78
+ String[] include() default {};
79
+ boolean aggregate() default false;
80
+ }
81
+
82
+ @Target(ElementType.METHOD)
83
+ @Retention(RetentionPolicy.RUNTIME)
84
+ public @interface TailorForClient {
85
+ ClientType value();
86
+ String[] fields() default {};
87
+ boolean compress() default false;
88
+ }
89
+ ```
90
+
91
+ ## Base BFF Controller
92
+
93
+ ```java
94
+ @RestController
95
+ @RequestMapping("/bff")
96
+ public abstract class BaseBffController {
97
+
98
+ protected final QueryCompositionService compositionService;
99
+ protected final ResponseTailoringService tailoringService;
100
+ protected final CombinedRateLimitService rateLimitService;
101
+
102
+ protected ClientType detectClient(HttpServletRequest request) {
103
+ String clientHeader = request.getHeader("X-Client-Type");
104
+ if (clientHeader != null) {
105
+ return ClientType.fromValue(clientHeader);
106
+ }
107
+
108
+ String userAgent = request.getHeader("User-Agent");
109
+ return ClientTypeDetector.fromUserAgent(userAgent);
110
+ }
111
+
112
+ protected <T> T tailorResponse(T response, ClientType clientType) {
113
+ return tailoringService.tailor(response, clientType);
114
+ }
115
+ }
116
+ ```
117
+
118
+ ## Query Composition Service
119
+
120
+ ```java
121
+ @Service
122
+ public class QueryCompositionServiceImpl implements QueryCompositionService {
123
+
124
+ private final List<ServiceRequest> serviceRequests;
125
+ private final ExecutorService executor;
126
+
127
+ @Override
128
+ public AggregatedResponse compose(List<String> includes,
129
+ Map<String, Object> params) {
130
+
131
+ List<CompletableFuture<ServiceResult>> futures = includes.stream()
132
+ .map(include -> findServiceRequest(include))
133
+ .map(sr -> CompletableFuture.supplyAsync(
134
+ () -> executeService(sr, params), executor)
135
+ .exceptionally(this::handleFailure))
136
+ .toList();
137
+
138
+ CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
139
+ .orTimeout(5, TimeUnit.SECONDS)
140
+ .join();
141
+
142
+ return aggregateResults(futures);
143
+ }
144
+
145
+ private ServiceResult handleFailure(Throwable ex) {
146
+ log.warn("Service call failed: {}", ex.getMessage());
147
+ return ServiceResult.failure(ex.getMessage());
148
+ }
149
+ }
150
+ ```
151
+
152
+ ## Response Tailoring Service
153
+
154
+ ```java
155
+ @Service
156
+ public class ResponseTailoringServiceImpl implements ResponseTailoringService {
157
+
158
+ private final ObjectMapper objectMapper;
159
+ private final Map<ClientType, Set<String>> fieldMappings;
160
+
161
+ @Override
162
+ @SuppressWarnings("unchecked")
163
+ public <T> T tailor(T response, ClientType clientType) {
164
+ if (response == null) return null;
165
+
166
+ Set<String> allowedFields = fieldMappings.get(clientType);
167
+ if (allowedFields == null || allowedFields.isEmpty()) {
168
+ return response;
169
+ }
170
+
171
+ // Convert to map, filter fields, convert back
172
+ Map<String, Object> map = objectMapper.convertValue(response, Map.class);
173
+ Map<String, Object> filtered = filterFields(map, allowedFields);
174
+
175
+ return (T) objectMapper.convertValue(filtered, response.getClass());
176
+ }
177
+
178
+ private Map<String, Object> filterFields(Map<String, Object> source,
179
+ Set<String> allowed) {
180
+ return source.entrySet().stream()
181
+ .filter(e -> allowed.contains(e.getKey()))
182
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
183
+ }
184
+ }
185
+ ```
186
+
187
+ ## Aggregated Response Model
188
+
189
+ ```java
190
+ public record AggregatedResponse(
191
+ Map<String, Object> data,
192
+ Map<String, ErrorInfo> errors,
193
+ ResponseMetadata metadata
194
+ ) {
195
+ public boolean hasErrors() {
196
+ return errors != null && !errors.isEmpty();
197
+ }
198
+
199
+ public static Builder builder() {
200
+ return new Builder();
201
+ }
202
+
203
+ public static class Builder {
204
+ private final Map<String, Object> data = new HashMap<>();
205
+ private final Map<String, ErrorInfo> errors = new HashMap<>();
206
+
207
+ public Builder addData(String key, Object value) {
208
+ data.put(key, value);
209
+ return this;
210
+ }
211
+
212
+ public Builder addError(String key, String message) {
213
+ errors.put(key, new ErrorInfo(message, null));
214
+ return this;
215
+ }
216
+
217
+ public AggregatedResponse build() {
218
+ return new AggregatedResponse(data, errors,
219
+ new ResponseMetadata(Instant.now()));
220
+ }
221
+ }
222
+ }
223
+ ```
224
+
225
+ ## BFF Endpoint Aspect
226
+
227
+ ```java
228
+ @Aspect
229
+ @Component
230
+ public class BffEndpointAspect {
231
+
232
+ private final CombinedRateLimitService rateLimitService;
233
+
234
+ @Around("@annotation(bffEndpoint)")
235
+ public Object handleBffEndpoint(ProceedingJoinPoint joinPoint,
236
+ BffEndpoint bffEndpoint) throws Throwable {
237
+
238
+ HttpServletRequest request = getCurrentRequest();
239
+ ClientType clientType = detectClient(request);
240
+
241
+ // Check client type restriction
242
+ if (bffEndpoint.clients().length > 0 &&
243
+ !Arrays.asList(bffEndpoint.clients()).contains(clientType)) {
244
+ throw new ClientTypeNotAllowedException(clientType);
245
+ }
246
+
247
+ // Apply rate limiting
248
+ rateLimitService.checkLimit(clientType, request);
249
+
250
+ return joinPoint.proceed();
251
+ }
252
+ }
253
+ ```
254
+
255
+ ## Example BFF Controller
256
+
257
+ ```java
258
+ @RestController
259
+ @RequestMapping("/bff/v1")
260
+ public class DashboardBffController extends BaseBffController {
261
+
262
+ private final UserService userService;
263
+ private final OrderService orderService;
264
+ private final NotificationService notificationService;
265
+
266
+ @GetMapping("/dashboard")
267
+ @BffEndpoint(aggregate = true)
268
+ public AggregatedResponse getDashboard(
269
+ @RequestParam(defaultValue = "profile,notifications") String include,
270
+ HttpServletRequest request) {
271
+
272
+ ClientType client = detectClient(request);
273
+ List<String> includes = Arrays.asList(include.split(","));
274
+
275
+ AggregatedResponse.Builder builder = AggregatedResponse.builder();
276
+
277
+ if (includes.contains("profile")) {
278
+ UserDTO profile = userService.getCurrentUser();
279
+ builder.addData("profile", tailorResponse(profile, client));
280
+ }
281
+
282
+ if (includes.contains("notifications")) {
283
+ int limit = client.isMobile() ? 5 : 20;
284
+ List<NotificationDTO> notifications =
285
+ notificationService.getRecent(limit);
286
+ builder.addData("notifications", notifications);
287
+ }
288
+
289
+ if (includes.contains("orders")) {
290
+ List<OrderDTO> orders = orderService.getRecentOrders();
291
+ builder.addData("orders", tailorResponse(orders, client));
292
+ }
293
+
294
+ return builder.build();
295
+ }
296
+
297
+ @GetMapping("/dashboard")
298
+ @TailorForClient(value = ClientType.MOBILE_IOS,
299
+ fields = {"id", "name", "avatarThumb"})
300
+ public MobileDashboardResponse getMobileDashboard() {
301
+ // iOS-specific optimized response
302
+ }
303
+ }
304
+ ```
305
+
306
+ ## Rate Limiting Service
307
+
308
+ ```java
309
+ @Service
310
+ public class CombinedRateLimitServiceImpl implements CombinedRateLimitService {
311
+
312
+ private final Map<ClientType, Bucket> buckets = new ConcurrentHashMap<>();
313
+ private final BffProperties properties;
314
+
315
+ @Override
316
+ public void checkLimit(ClientType clientType, HttpServletRequest request) {
317
+ Bucket bucket = buckets.computeIfAbsent(clientType, this::createBucket);
318
+
319
+ if (!bucket.tryConsume(1)) {
320
+ throw new RateLimitExceededException(
321
+ "Rate limit exceeded for client type: " + clientType);
322
+ }
323
+ }
324
+
325
+ private Bucket createBucket(ClientType clientType) {
326
+ int rpm = properties.getRateLimits()
327
+ .getOrDefault(clientType, 100);
328
+
329
+ return Bucket.builder()
330
+ .addLimit(Bandwidth.simple(rpm, Duration.ofMinutes(1)))
331
+ .build();
332
+ }
333
+ }
334
+ ```
335
+
336
+ ## Testing
337
+
338
+ ```java
339
+ @WebMvcTest(DashboardBffController.class)
340
+ class DashboardBffControllerTest {
341
+
342
+ @Autowired
343
+ private MockMvc mockMvc;
344
+
345
+ @MockBean
346
+ private UserService userService;
347
+
348
+ @Test
349
+ void shouldTailorResponseForMobile() throws Exception {
350
+ when(userService.getCurrentUser()).thenReturn(fullUserDto());
351
+
352
+ mockMvc.perform(get("/bff/v1/dashboard")
353
+ .header("X-Client-Type", "ios"))
354
+ .andExpect(status().isOk())
355
+ .andExpect(jsonPath("$.data.profile.email").doesNotExist())
356
+ .andExpect(jsonPath("$.data.profile.id").exists());
357
+ }
358
+ }
359
+ ```
360
+
361
+ ## Related Skills
362
+
363
+ - `bff-concepts`: BFF pattern concepts
364
+ - `spring-boot-4`: Spring Boot 4.0 patterns