@girardelli/architect-agents 8.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 (258) hide show
  1. package/dist/src/core/agent-generator/context-enricher.d.ts +17 -0
  2. package/dist/src/core/agent-generator/context-enricher.js +51 -0
  3. package/dist/src/core/agent-generator/context-enricher.js.map +1 -0
  4. package/dist/src/core/agent-generator/detectors/base-detector.d.ts +8 -0
  5. package/dist/src/core/agent-generator/detectors/base-detector.js +12 -0
  6. package/dist/src/core/agent-generator/detectors/base-detector.js.map +1 -0
  7. package/dist/src/core/agent-generator/detectors/dart-detector.d.ts +5 -0
  8. package/dist/src/core/agent-generator/detectors/dart-detector.js +16 -0
  9. package/dist/src/core/agent-generator/detectors/dart-detector.js.map +1 -0
  10. package/dist/src/core/agent-generator/detectors/framework-registry.d.ts +5 -0
  11. package/dist/src/core/agent-generator/detectors/framework-registry.js +81 -0
  12. package/dist/src/core/agent-generator/detectors/framework-registry.js.map +1 -0
  13. package/dist/src/core/agent-generator/detectors/go-detector.d.ts +5 -0
  14. package/dist/src/core/agent-generator/detectors/go-detector.js +25 -0
  15. package/dist/src/core/agent-generator/detectors/go-detector.js.map +1 -0
  16. package/dist/src/core/agent-generator/detectors/java-detector.d.ts +5 -0
  17. package/dist/src/core/agent-generator/detectors/java-detector.js +44 -0
  18. package/dist/src/core/agent-generator/detectors/java-detector.js.map +1 -0
  19. package/dist/src/core/agent-generator/detectors/node-detector.d.ts +5 -0
  20. package/dist/src/core/agent-generator/detectors/node-detector.js +28 -0
  21. package/dist/src/core/agent-generator/detectors/node-detector.js.map +1 -0
  22. package/dist/src/core/agent-generator/detectors/php-detector.d.ts +5 -0
  23. package/dist/src/core/agent-generator/detectors/php-detector.js +28 -0
  24. package/dist/src/core/agent-generator/detectors/php-detector.js.map +1 -0
  25. package/dist/src/core/agent-generator/detectors/python-detector.d.ts +7 -0
  26. package/dist/src/core/agent-generator/detectors/python-detector.js +116 -0
  27. package/dist/src/core/agent-generator/detectors/python-detector.js.map +1 -0
  28. package/dist/src/core/agent-generator/detectors/ruby-detector.d.ts +5 -0
  29. package/dist/src/core/agent-generator/detectors/ruby-detector.js +23 -0
  30. package/dist/src/core/agent-generator/detectors/ruby-detector.js.map +1 -0
  31. package/dist/src/core/agent-generator/detectors/rust-detector.d.ts +5 -0
  32. package/dist/src/core/agent-generator/detectors/rust-detector.js +18 -0
  33. package/dist/src/core/agent-generator/detectors/rust-detector.js.map +1 -0
  34. package/dist/src/core/agent-generator/detectors/structure-detector.d.ts +4 -0
  35. package/dist/src/core/agent-generator/detectors/structure-detector.js +35 -0
  36. package/dist/src/core/agent-generator/detectors/structure-detector.js.map +1 -0
  37. package/dist/src/core/agent-generator/detectors/toolchain-detector.d.ts +5 -0
  38. package/dist/src/core/agent-generator/detectors/toolchain-detector.js +164 -0
  39. package/dist/src/core/agent-generator/detectors/toolchain-detector.js.map +1 -0
  40. package/dist/src/core/agent-generator/domain-inferrer.d.ts +51 -0
  41. package/dist/src/core/agent-generator/domain-inferrer.js +585 -0
  42. package/dist/src/core/agent-generator/domain-inferrer.js.map +1 -0
  43. package/dist/src/core/agent-generator/engines/audit-engine.d.ts +8 -0
  44. package/dist/src/core/agent-generator/engines/audit-engine.js +84 -0
  45. package/dist/src/core/agent-generator/engines/audit-engine.js.map +1 -0
  46. package/dist/src/core/agent-generator/engines/context-builder.d.ts +12 -0
  47. package/dist/src/core/agent-generator/engines/context-builder.js +84 -0
  48. package/dist/src/core/agent-generator/engines/context-builder.js.map +1 -0
  49. package/dist/src/core/agent-generator/engines/generation-engine.d.ts +7 -0
  50. package/dist/src/core/agent-generator/engines/generation-engine.js +160 -0
  51. package/dist/src/core/agent-generator/engines/generation-engine.js.map +1 -0
  52. package/dist/src/core/agent-generator/engines/generation-engine_deps.d.ts +21 -0
  53. package/dist/src/core/agent-generator/engines/generation-engine_deps.js +17 -0
  54. package/dist/src/core/agent-generator/engines/generation-engine_deps.js.map +1 -0
  55. package/dist/src/core/agent-generator/engines/suggestion-engine.d.ts +13 -0
  56. package/dist/src/core/agent-generator/engines/suggestion-engine.js +171 -0
  57. package/dist/src/core/agent-generator/engines/suggestion-engine.js.map +1 -0
  58. package/dist/src/core/agent-generator/engines/suggestion-engine_deps.d.ts +8 -0
  59. package/dist/src/core/agent-generator/engines/suggestion-engine_deps.js +5 -0
  60. package/dist/src/core/agent-generator/engines/suggestion-engine_deps.js.map +1 -0
  61. package/dist/src/core/agent-generator/enrichers/analysis-helpers.d.ts +9 -0
  62. package/dist/src/core/agent-generator/enrichers/analysis-helpers.js +51 -0
  63. package/dist/src/core/agent-generator/enrichers/analysis-helpers.js.map +1 -0
  64. package/dist/src/core/agent-generator/enrichers/description-generator.d.ts +4 -0
  65. package/dist/src/core/agent-generator/enrichers/description-generator.js +82 -0
  66. package/dist/src/core/agent-generator/enrichers/description-generator.js.map +1 -0
  67. package/dist/src/core/agent-generator/enrichers/endpoint-extractor.d.ts +7 -0
  68. package/dist/src/core/agent-generator/enrichers/endpoint-extractor.js +90 -0
  69. package/dist/src/core/agent-generator/enrichers/endpoint-extractor.js.map +1 -0
  70. package/dist/src/core/agent-generator/enrichers/layer-classifier.d.ts +12 -0
  71. package/dist/src/core/agent-generator/enrichers/layer-classifier.js +152 -0
  72. package/dist/src/core/agent-generator/enrichers/layer-classifier.js.map +1 -0
  73. package/dist/src/core/agent-generator/enrichers/module-extractor.d.ts +10 -0
  74. package/dist/src/core/agent-generator/enrichers/module-extractor.js +173 -0
  75. package/dist/src/core/agent-generator/enrichers/module-extractor.js.map +1 -0
  76. package/dist/src/core/agent-generator/framework-detector.d.ts +17 -0
  77. package/dist/src/core/agent-generator/framework-detector.js +56 -0
  78. package/dist/src/core/agent-generator/framework-detector.js.map +1 -0
  79. package/dist/src/core/agent-generator/index.d.ts +25 -0
  80. package/dist/src/core/agent-generator/index.js +37 -0
  81. package/dist/src/core/agent-generator/index.js.map +1 -0
  82. package/dist/src/core/agent-generator/stack-detector.d.ts +13 -0
  83. package/dist/src/core/agent-generator/stack-detector.js +124 -0
  84. package/dist/src/core/agent-generator/stack-detector.js.map +1 -0
  85. package/dist/src/core/agent-generator/templates/core/agents.d.ts +9 -0
  86. package/dist/src/core/agent-generator/templates/core/agents.js +1127 -0
  87. package/dist/src/core/agent-generator/templates/core/agents.js.map +1 -0
  88. package/dist/src/core/agent-generator/templates/core/architecture-rules.d.ts +6 -0
  89. package/dist/src/core/agent-generator/templates/core/architecture-rules.js +275 -0
  90. package/dist/src/core/agent-generator/templates/core/architecture-rules.js.map +1 -0
  91. package/dist/src/core/agent-generator/templates/core/general-rules.d.ts +7 -0
  92. package/dist/src/core/agent-generator/templates/core/general-rules.js +301 -0
  93. package/dist/src/core/agent-generator/templates/core/general-rules.js.map +1 -0
  94. package/dist/src/core/agent-generator/templates/core/hooks-generator.d.ts +20 -0
  95. package/dist/src/core/agent-generator/templates/core/hooks-generator.js +235 -0
  96. package/dist/src/core/agent-generator/templates/core/hooks-generator.js.map +1 -0
  97. package/dist/src/core/agent-generator/templates/core/index-md.d.ts +6 -0
  98. package/dist/src/core/agent-generator/templates/core/index-md.js +247 -0
  99. package/dist/src/core/agent-generator/templates/core/index-md.js.map +1 -0
  100. package/dist/src/core/agent-generator/templates/core/orchestrator.d.ts +7 -0
  101. package/dist/src/core/agent-generator/templates/core/orchestrator.js +423 -0
  102. package/dist/src/core/agent-generator/templates/core/orchestrator.js.map +1 -0
  103. package/dist/src/core/agent-generator/templates/core/preflight.d.ts +7 -0
  104. package/dist/src/core/agent-generator/templates/core/preflight.js +213 -0
  105. package/dist/src/core/agent-generator/templates/core/preflight.js.map +1 -0
  106. package/dist/src/core/agent-generator/templates/core/quality-gates.d.ts +10 -0
  107. package/dist/src/core/agent-generator/templates/core/quality-gates.js +255 -0
  108. package/dist/src/core/agent-generator/templates/core/quality-gates.js.map +1 -0
  109. package/dist/src/core/agent-generator/templates/core/security-rules.d.ts +6 -0
  110. package/dist/src/core/agent-generator/templates/core/security-rules.js +529 -0
  111. package/dist/src/core/agent-generator/templates/core/security-rules.js.map +1 -0
  112. package/dist/src/core/agent-generator/templates/core/skills-generator.d.ts +18 -0
  113. package/dist/src/core/agent-generator/templates/core/skills-generator.js +547 -0
  114. package/dist/src/core/agent-generator/templates/core/skills-generator.js.map +1 -0
  115. package/dist/src/core/agent-generator/templates/core/workflow-fix-bug.d.ts +6 -0
  116. package/dist/src/core/agent-generator/templates/core/workflow-fix-bug.js +238 -0
  117. package/dist/src/core/agent-generator/templates/core/workflow-fix-bug.js.map +1 -0
  118. package/dist/src/core/agent-generator/templates/core/workflow-new-feature.d.ts +7 -0
  119. package/dist/src/core/agent-generator/templates/core/workflow-new-feature.js +321 -0
  120. package/dist/src/core/agent-generator/templates/core/workflow-new-feature.js.map +1 -0
  121. package/dist/src/core/agent-generator/templates/core/workflow-review.d.ts +6 -0
  122. package/dist/src/core/agent-generator/templates/core/workflow-review.js +105 -0
  123. package/dist/src/core/agent-generator/templates/core/workflow-review.js.map +1 -0
  124. package/dist/src/core/agent-generator/templates/domain/index.d.ts +21 -0
  125. package/dist/src/core/agent-generator/templates/domain/index.js +1179 -0
  126. package/dist/src/core/agent-generator/templates/domain/index.js.map +1 -0
  127. package/dist/src/core/agent-generator/templates/helpers/base-helpers.d.ts +10 -0
  128. package/dist/src/core/agent-generator/templates/helpers/base-helpers.js +20 -0
  129. package/dist/src/core/agent-generator/templates/helpers/base-helpers.js.map +1 -0
  130. package/dist/src/core/agent-generator/templates/helpers/cross-ref-helpers.d.ts +2 -0
  131. package/dist/src/core/agent-generator/templates/helpers/cross-ref-helpers.js +77 -0
  132. package/dist/src/core/agent-generator/templates/helpers/cross-ref-helpers.js.map +1 -0
  133. package/dist/src/core/agent-generator/templates/helpers/security-helpers.d.ts +2 -0
  134. package/dist/src/core/agent-generator/templates/helpers/security-helpers.js +182 -0
  135. package/dist/src/core/agent-generator/templates/helpers/security-helpers.js.map +1 -0
  136. package/dist/src/core/agent-generator/templates/helpers/stack-helpers.d.ts +4 -0
  137. package/dist/src/core/agent-generator/templates/helpers/stack-helpers.js +69 -0
  138. package/dist/src/core/agent-generator/templates/helpers/stack-helpers.js.map +1 -0
  139. package/dist/src/core/agent-generator/templates/helpers/structure-helpers.d.ts +2 -0
  140. package/dist/src/core/agent-generator/templates/helpers/structure-helpers.js +275 -0
  141. package/dist/src/core/agent-generator/templates/helpers/structure-helpers.js.map +1 -0
  142. package/dist/src/core/agent-generator/templates/helpers/summary-helpers.d.ts +6 -0
  143. package/dist/src/core/agent-generator/templates/helpers/summary-helpers.js +56 -0
  144. package/dist/src/core/agent-generator/templates/helpers/summary-helpers.js.map +1 -0
  145. package/dist/src/core/agent-generator/templates/stack/index.d.ts +7 -0
  146. package/dist/src/core/agent-generator/templates/stack/index.js +695 -0
  147. package/dist/src/core/agent-generator/templates/stack/index.js.map +1 -0
  148. package/dist/src/core/agent-generator/templates/template-helpers.d.ts +11 -0
  149. package/dist/src/core/agent-generator/templates/template-helpers.js +12 -0
  150. package/dist/src/core/agent-generator/templates/template-helpers.js.map +1 -0
  151. package/dist/src/core/agent-generator/types/agent.d.ts +39 -0
  152. package/dist/src/core/agent-generator/types/agent.js +27 -0
  153. package/dist/src/core/agent-generator/types/agent.js.map +1 -0
  154. package/dist/src/core/agent-generator/types/domain.d.ts +58 -0
  155. package/dist/src/core/agent-generator/types/domain.js +2 -0
  156. package/dist/src/core/agent-generator/types/domain.js.map +1 -0
  157. package/dist/src/core/agent-generator/types/stack.d.ts +36 -0
  158. package/dist/src/core/agent-generator/types/stack.js +2 -0
  159. package/dist/src/core/agent-generator/types/stack.js.map +1 -0
  160. package/dist/src/core/agent-generator/types/template.d.ts +29 -0
  161. package/dist/src/core/agent-generator/types/template.js +2 -0
  162. package/dist/src/core/agent-generator/types/template.js.map +1 -0
  163. package/dist/src/core/agent-runtime/ai-provider.d.ts +33 -0
  164. package/dist/src/core/agent-runtime/ai-provider.js +146 -0
  165. package/dist/src/core/agent-runtime/ai-provider.js.map +1 -0
  166. package/dist/src/core/agent-runtime/executor.d.ts +13 -0
  167. package/dist/src/core/agent-runtime/executor.js +138 -0
  168. package/dist/src/core/agent-runtime/executor.js.map +1 -0
  169. package/dist/src/core/agent-runtime/human-gate.d.ts +16 -0
  170. package/dist/src/core/agent-runtime/human-gate.js +70 -0
  171. package/dist/src/core/agent-runtime/human-gate.js.map +1 -0
  172. package/dist/tests/agent-generator.test.d.ts +1 -0
  173. package/dist/tests/agent-generator.test.js +349 -0
  174. package/dist/tests/agent-generator.test.js.map +1 -0
  175. package/dist/tests/agent-runtime.test.d.ts +1 -0
  176. package/dist/tests/agent-runtime.test.js +107 -0
  177. package/dist/tests/agent-runtime.test.js.map +1 -0
  178. package/dist/tests/context-enricher.test.d.ts +1 -0
  179. package/dist/tests/context-enricher.test.js +875 -0
  180. package/dist/tests/context-enricher.test.js.map +1 -0
  181. package/dist/tests/framework-detector.test.d.ts +1 -0
  182. package/dist/tests/framework-detector.test.js +882 -0
  183. package/dist/tests/framework-detector.test.js.map +1 -0
  184. package/dist/tests/stack-detector.test.d.ts +1 -0
  185. package/dist/tests/stack-detector.test.js +183 -0
  186. package/dist/tests/stack-detector.test.js.map +1 -0
  187. package/dist/tests/template-generation.test.d.ts +1 -0
  188. package/dist/tests/template-generation.test.js +571 -0
  189. package/dist/tests/template-generation.test.js.map +1 -0
  190. package/dist/tests/template-helpers.test.d.ts +1 -0
  191. package/dist/tests/template-helpers.test.js +967 -0
  192. package/dist/tests/template-helpers.test.js.map +1 -0
  193. package/package.json +24 -0
  194. package/src/core/agent-generator/context-enricher.ts +67 -0
  195. package/src/core/agent-generator/detectors/base-detector.ts +18 -0
  196. package/src/core/agent-generator/detectors/dart-detector.ts +17 -0
  197. package/src/core/agent-generator/detectors/framework-registry.ts +82 -0
  198. package/src/core/agent-generator/detectors/go-detector.ts +26 -0
  199. package/src/core/agent-generator/detectors/java-detector.ts +46 -0
  200. package/src/core/agent-generator/detectors/node-detector.ts +28 -0
  201. package/src/core/agent-generator/detectors/php-detector.ts +28 -0
  202. package/src/core/agent-generator/detectors/python-detector.ts +125 -0
  203. package/src/core/agent-generator/detectors/ruby-detector.ts +24 -0
  204. package/src/core/agent-generator/detectors/rust-detector.ts +19 -0
  205. package/src/core/agent-generator/detectors/structure-detector.ts +38 -0
  206. package/src/core/agent-generator/detectors/toolchain-detector.ts +181 -0
  207. package/src/core/agent-generator/domain-inferrer.ts +630 -0
  208. package/src/core/agent-generator/engines/audit-engine.ts +98 -0
  209. package/src/core/agent-generator/engines/context-builder.ts +96 -0
  210. package/src/core/agent-generator/engines/generation-engine.ts +184 -0
  211. package/src/core/agent-generator/engines/generation-engine_deps.ts +21 -0
  212. package/src/core/agent-generator/engines/suggestion-engine.ts +202 -0
  213. package/src/core/agent-generator/engines/suggestion-engine_deps.ts +8 -0
  214. package/src/core/agent-generator/enrichers/analysis-helpers.ts +58 -0
  215. package/src/core/agent-generator/enrichers/description-generator.ts +91 -0
  216. package/src/core/agent-generator/enrichers/endpoint-extractor.ts +114 -0
  217. package/src/core/agent-generator/enrichers/layer-classifier.ts +156 -0
  218. package/src/core/agent-generator/enrichers/module-extractor.ts +203 -0
  219. package/src/core/agent-generator/framework-detector.ts +66 -0
  220. package/src/core/agent-generator/index.ts +55 -0
  221. package/src/core/agent-generator/stack-detector.ts +115 -0
  222. package/src/core/agent-generator/templates/core/agents.ts +1168 -0
  223. package/src/core/agent-generator/templates/core/architecture-rules.ts +288 -0
  224. package/src/core/agent-generator/templates/core/general-rules.ts +306 -0
  225. package/src/core/agent-generator/templates/core/hooks-generator.ts +244 -0
  226. package/src/core/agent-generator/templates/core/index-md.ts +261 -0
  227. package/src/core/agent-generator/templates/core/orchestrator.ts +462 -0
  228. package/src/core/agent-generator/templates/core/preflight.ts +216 -0
  229. package/src/core/agent-generator/templates/core/quality-gates.ts +257 -0
  230. package/src/core/agent-generator/templates/core/security-rules.ts +544 -0
  231. package/src/core/agent-generator/templates/core/skills-generator.ts +586 -0
  232. package/src/core/agent-generator/templates/core/workflow-fix-bug.ts +240 -0
  233. package/src/core/agent-generator/templates/core/workflow-new-feature.ts +323 -0
  234. package/src/core/agent-generator/templates/core/workflow-review.ts +107 -0
  235. package/src/core/agent-generator/templates/domain/index.ts +1204 -0
  236. package/src/core/agent-generator/templates/helpers/base-helpers.ts +33 -0
  237. package/src/core/agent-generator/templates/helpers/cross-ref-helpers.ts +79 -0
  238. package/src/core/agent-generator/templates/helpers/security-helpers.ts +198 -0
  239. package/src/core/agent-generator/templates/helpers/stack-helpers.ts +80 -0
  240. package/src/core/agent-generator/templates/helpers/structure-helpers.ts +293 -0
  241. package/src/core/agent-generator/templates/helpers/summary-helpers.ts +67 -0
  242. package/src/core/agent-generator/templates/stack/index.ts +705 -0
  243. package/src/core/agent-generator/templates/template-helpers.ts +12 -0
  244. package/src/core/agent-generator/types/agent.ts +65 -0
  245. package/src/core/agent-generator/types/domain.ts +63 -0
  246. package/src/core/agent-generator/types/stack.ts +38 -0
  247. package/src/core/agent-generator/types/template.ts +31 -0
  248. package/src/core/agent-runtime/ai-provider.ts +178 -0
  249. package/src/core/agent-runtime/executor.ts +148 -0
  250. package/src/core/agent-runtime/human-gate.ts +69 -0
  251. package/tests/agent-generator.test.ts +428 -0
  252. package/tests/agent-runtime.test.ts +125 -0
  253. package/tests/context-enricher.test.ts +972 -0
  254. package/tests/framework-detector.test.ts +1172 -0
  255. package/tests/stack-detector.test.ts +241 -0
  256. package/tests/template-generation.test.ts +709 -0
  257. package/tests/template-helpers.test.ts +1130 -0
  258. package/tsconfig.json +14 -0
@@ -0,0 +1,1204 @@
1
+ import { TemplateContext, EnrichedTemplateContext } from '@girardelli/architect-agents/src/core/agent-generator/types/template.js';
2
+
3
+ /**
4
+ * Domain templates — C4, BDD, TDD, ADR, Threat Model.
5
+ * Reutilizable templates referenced by workflows and agents.
6
+ */
7
+
8
+ /**
9
+ * Helper to safely extract enriched context
10
+ */
11
+ function getEnriched(ctx?: TemplateContext): Partial<EnrichedTemplateContext> {
12
+ if (ctx && 'domain' in ctx) {
13
+ return ctx as EnrichedTemplateContext;
14
+ }
15
+ return {};
16
+ }
17
+
18
+ /**
19
+ * Generate C4 Architecture template with optional pre-filled examples
20
+ */
21
+ export function generateC4Template(ctx?: EnrichedTemplateContext | TemplateContext): string {
22
+ const enriched = getEnriched(ctx);
23
+ const domain = enriched.domain;
24
+ const modules = enriched.modules || [];
25
+ const endpoints = enriched.endpoints || [];
26
+ const integrations = domain?.integrations || [];
27
+
28
+ // Build Level 1 content
29
+ let level1Content = `Atores:
30
+ - [ator 1]: [descrição do papel]
31
+ - [ator 2]: [descrição do papel]`;
32
+
33
+ if (domain?.businessEntities && domain.businessEntities.length > 0) {
34
+ const actorsFromEntities = domain.businessEntities.slice(0, 2).map((e) => `- ${e.name}: Entidade de negócio`).join('\n');
35
+ level1Content = `Atores:\n${actorsFromEntities}`;
36
+ }
37
+
38
+ let externalSystems = `- [sistema 1]: [como interage]
39
+ - [sistema 2]: [como interage]`;
40
+
41
+ if (integrations.length > 0) {
42
+ externalSystems = integrations
43
+ .map((i) => `- ${i.name} (${i.type}): Integração de negócio`)
44
+ .join('\n');
45
+ }
46
+
47
+ // Build Level 2 content
48
+ let containerDiagram = `┌──────────────┐ ┌──────────────┐ ┌──────────────┐
49
+ │ Frontend │───▶│ Backend │───▶│ Database │
50
+ │ (Web/App) │ │ (API) │ │ (PostgreSQL)│
51
+ └──────────────┘ └──────────────┘ └──────────────┘
52
+
53
+
54
+ ┌──────────────┐
55
+ │ External │
56
+ │ Service │
57
+ └──────────────┘`;
58
+
59
+ if (ctx && 'stack' in ctx && ctx.stack) {
60
+ const stack = ctx.stack;
61
+ let frontendLabel = stack.hasFrontend ? `${stack.frameworks[0] || 'Frontend'}` : '[Frontend]';
62
+ let backendLabel = stack.frameworks[1] || 'Backend';
63
+ let dbLabel = '[Database]';
64
+ if (stack.hasDatabase) {
65
+ dbLabel = stack.frameworks.includes('PostgreSQL') ? 'PostgreSQL' : 'Database';
66
+ }
67
+
68
+ containerDiagram = `┌──────────────┐ ┌──────────────┐ ┌──────────────┐
69
+ │ ${frontendLabel.padEnd(11)}│───▶│ ${backendLabel.padEnd(11)}│───▶│ ${dbLabel.padEnd(11)}│
70
+ └──────────────┘ └──────────────┘ └──────────────┘`;
71
+ }
72
+
73
+ // Build Level 3 content
74
+ let componentContent = `Módulo: [nome]
75
+ ├── Controller: [nome] — [responsabilidade]
76
+ ├── Service: [nome] — [responsabilidade]
77
+ ├── Entity: [nome] — [campos principais]
78
+ ├── DTO: [nome] — [campos de request/response]
79
+ └── Tests: [lista de testes]`;
80
+
81
+ if (modules.length > 0) {
82
+ const firstModule = modules[0];
83
+ const controllers = firstModule.controllers.slice(0, 2).join(', ') || '[Controllers]';
84
+ const services = firstModule.services.slice(0, 2).join(', ') || '[Services]';
85
+ const entities = firstModule.entities.slice(0, 1).join(', ') || '[Entities]';
86
+
87
+ componentContent = `Módulo: ${firstModule.name}
88
+ ├── Controller: ${controllers} — Expõe endpoints REST
89
+ ├── Service: ${services} — Lógica de negócio
90
+ ├── Entity: ${entities} — Persistência de dados
91
+ ├── DTO: [Request/Response]
92
+ └── Tests: ${firstModule.testFiles.length > 0 ? 'Implementados' : 'Pendentes'}`;
93
+ }
94
+
95
+ // Build Level 4 content — framework-aware code example
96
+ const stack = ctx && 'stack' in ctx ? ctx.stack : undefined;
97
+ const langs = stack ? stack.languages.map((l) => l.toLowerCase()) : [];
98
+ const isPython = langs.includes('python');
99
+ const isDart = langs.includes('dart');
100
+ const isJava = langs.includes('java') || langs.includes('kotlin');
101
+ const isGo = langs.includes('go');
102
+ const isRust = langs.includes('rust');
103
+
104
+ let level4Lang = 'typescript';
105
+ let level4Content = `interface IExemploService {
106
+ metodo(param: Tipo): Promise<Retorno>;
107
+ }`;
108
+
109
+ if (isPython) {
110
+ level4Lang = 'python';
111
+ level4Content = `class IExemploService(ABC):
112
+ @abstractmethod
113
+ async def metodo(self, param: Tipo) -> Retorno:
114
+ ...`;
115
+ } else if (isDart) {
116
+ level4Lang = 'dart';
117
+ level4Content = `abstract class IExemploService {
118
+ Future<Retorno> metodo(Tipo param);
119
+ }`;
120
+ } else if (isJava) {
121
+ level4Lang = 'java';
122
+ level4Content = `public interface IExemploService {
123
+ Retorno metodo(Tipo param);
124
+ }`;
125
+ } else if (isGo) {
126
+ level4Lang = 'go';
127
+ level4Content = `type ExemploService interface {
128
+ Metodo(param Tipo) (Retorno, error)
129
+ }`;
130
+ } else if (isRust) {
131
+ level4Lang = 'rust';
132
+ level4Content = `trait ExemploService {
133
+ fn metodo(&self, param: Tipo) -> Result<Retorno, Error>;
134
+ }`;
135
+ }
136
+
137
+ if (endpoints.length > 0) {
138
+ const firstEndpoint = endpoints[0];
139
+ if (isPython) {
140
+ level4Content = `class I${firstEndpoint.handler}Service(ABC):
141
+ # ${firstEndpoint.method} ${firstEndpoint.path}
142
+ @abstractmethod
143
+ async def handle_${firstEndpoint.handler.toLowerCase()}(self, req: Request) -> Response:
144
+ ...`;
145
+ } else if (isDart) {
146
+ level4Content = `abstract class I${firstEndpoint.handler}Service {
147
+ // ${firstEndpoint.method} ${firstEndpoint.path}
148
+ Future<Response> handle${firstEndpoint.handler}(Request req);
149
+ }`;
150
+ } else if (isJava) {
151
+ level4Content = `public interface I${firstEndpoint.handler}Service {
152
+ // ${firstEndpoint.method} ${firstEndpoint.path}
153
+ Response handle${firstEndpoint.handler}(Request req);
154
+ }`;
155
+ } else if (isGo) {
156
+ level4Content = `type ${firstEndpoint.handler}Service interface {
157
+ // ${firstEndpoint.method} ${firstEndpoint.path}
158
+ Handle${firstEndpoint.handler}(req *Request) (*Response, error)
159
+ }`;
160
+ } else {
161
+ level4Content = `interface I${firstEndpoint.handler}Service {
162
+ // ${firstEndpoint.method} ${firstEndpoint.path}
163
+ handle${firstEndpoint.handler}(req: Request): Promise<Response>;
164
+ }`;
165
+ }
166
+ }
167
+
168
+ return `# 🏗️ Template: Arquitetura C4
169
+
170
+ > Preencher os 4 níveis relevantes para a feature/mudança.
171
+
172
+ ---
173
+
174
+ ## Nível 1 — Contexto
175
+
176
+ > Visão de pássaro: quem são os atores e sistemas envolvidos?
177
+
178
+ \`\`\`
179
+ ${level1Content}
180
+
181
+ Sistemas Externos:
182
+ ${externalSystems}
183
+
184
+ Fluxo de dados:
185
+ [ator] → [sistema] → [nosso sistema] → [resposta]
186
+ \`\`\`
187
+
188
+ ---
189
+
190
+ ## Nível 2 — Container
191
+
192
+ > Quais serviços, apps, bancos de dados são tocados?
193
+
194
+ \`\`\`
195
+ ${containerDiagram}
196
+ \`\`\`
197
+
198
+ ---
199
+
200
+ ## Nível 3 — Componente
201
+
202
+ > Quais módulos, classes, serviços são criados ou modificados?
203
+
204
+ \`\`\`
205
+ ${componentContent}
206
+ \`\`\`
207
+
208
+ ---
209
+
210
+ ## Nível 4 — Código (se complexo)
211
+
212
+ > Interfaces, tipos, contratos. Apenas para decisões complexas.
213
+
214
+ \`\`\`${level4Lang}
215
+ ${level4Content}
216
+ \`\`\`
217
+
218
+ ---
219
+
220
+ ## Decisões Arquiteturais
221
+
222
+ Se a decisão é significativa → criar ADR separado (ver template ADR).
223
+ `;
224
+ }
225
+
226
+ /**
227
+ * Generate BDD template with optional pre-filled examples from project domain
228
+ */
229
+ export function generateBddTemplate(ctx?: EnrichedTemplateContext | TemplateContext): string {
230
+ const enriched = getEnriched(ctx);
231
+ const domain = enriched.domain;
232
+ const businessEntities = domain?.businessEntities || [];
233
+ const compliance = domain?.compliance || [];
234
+
235
+ let featureName = '[Nome da Feature]';
236
+ let exampleScenario = ` Scenario: [cenário principal - sucesso]
237
+ Given [contexto / pré-condição]
238
+ And [contexto adicional, se necessário]
239
+ When [ação do usuário]
240
+ Then [resultado esperado]
241
+ And [efeito colateral, se houver]`;
242
+
243
+ // Generate example scenario from first business entity
244
+ if (businessEntities.length > 0) {
245
+ const entity = businessEntities[0];
246
+ featureName = `Criar e Validar ${entity.name}`;
247
+ exampleScenario = ` Scenario: Criar ${entity.name} com sucesso
248
+ Given o usuário está no formulário de criação de ${entity.name}
249
+ And todos os campos obrigatórios estão vazios
250
+ When o usuário preenche os campos corretamente
251
+ Then a entidade é persistida no banco de dados
252
+ And uma mensagem de sucesso é exibida ao usuário`;
253
+ }
254
+
255
+ let complianceScenario = ` Scenario: [cenário de acesso negado]
256
+ Given [usuário sem permissão]
257
+ When [tenta acessar recurso]
258
+ Then [resposta 403 / redirect]`;
259
+
260
+ // Add compliance-specific scenario if applicable
261
+ if (compliance.length > 0) {
262
+ const comp = compliance[0];
263
+ if (comp.name === 'LGPD') {
264
+ complianceScenario = ` Scenario: Usuário solicita exclusão de dados sob LGPD
265
+ Given um usuário autenticado no sistema
266
+ When o usuário solicita a exclusão de seus dados pessoais
267
+ Then todos os seus registros são anonimizados ou removidos
268
+ And a solicitação é registrada em audit log`;
269
+ } else if (comp.name === 'HIPAA') {
270
+ complianceScenario = ` Scenario: Acesso a dados sensíveis de paciente
271
+ Given um profissional de saúde autenticado
272
+ When o profissional acessa registros de paciente
273
+ Then o acesso é registrado com timestamp e usuário
274
+ And a ação é auditada para compliance`;
275
+ }
276
+ }
277
+
278
+ let domainSpecificSection = '';
279
+ if (domain?.domain === 'fintech' || domain?.domain === 'payment') {
280
+ domainSpecificSection = `
281
+
282
+ # ── Cenários de Fintech ──
283
+
284
+ Scenario: Transação com saldo insuficiente
285
+ Given a conta do usuário tem saldo de R$ 50
286
+ When o usuário tenta transferir R$ 100
287
+ Then a transação é rejeitada
288
+ And a mensagem "Saldo insuficiente" é exibida
289
+
290
+ Scenario: Taxa de câmbio atualizada
291
+ Given uma transação internacional está pendente
292
+ When a taxa de câmbio muda de 5.0 para 5.2
293
+ Then o valor em reais é recalculado
294
+ And o usuário é notificado da mudança`;
295
+ } else if (domain?.domain === 'tax' || domain?.subDomain === 'tax-processing') {
296
+ domainSpecificSection = `
297
+
298
+ # ── Cenários de Impostos ──
299
+
300
+ Scenario: Calcular imposto sobre renda
301
+ Given um contribuinte com rendimento mensal de R$ 5000
302
+ When o sistema calcula o imposto devido
303
+ Then o valor segue a tabela progressiva do IRPF
304
+ And o resultado é salvo no banco de dados
305
+
306
+ Scenario: Gerar DARF automático
307
+ Given uma obrigação de imposto vencendo amanhã
308
+ When o sistema processa as obrigações pendentes
309
+ Then um DARF é gerado automaticamente
310
+ And uma notificação é enviada ao contribuinte`;
311
+ }
312
+
313
+ return `# 🧪 Template: BDD — Behavior-Driven Development
314
+
315
+ > Um cenário para cada critério de aceite + cenários de erro + edge cases.
316
+
317
+ ---
318
+
319
+ ## Feature: ${featureName}
320
+
321
+ \`\`\`gherkin
322
+ Feature: ${featureName}
323
+ Como usuário,
324
+ Quero interagir com ${businessEntities[0]?.name || 'o sistema'},
325
+ Para alcançar meu objetivo de negócio.
326
+
327
+ # ── Happy Path ──
328
+
329
+ ${exampleScenario}
330
+
331
+ # ── Validações ──
332
+
333
+ Scenario: Validação de dados obrigatórios
334
+ Given um formulário de criação
335
+ When o usuário tenta enviar sem preencher campos obrigatórios
336
+ Then mensagens de erro são exibidas para cada campo
337
+
338
+ # ── Edge Cases ──
339
+
340
+ Scenario: Lidar com valores boundary
341
+ Given o sistema aceita valores de 0 a 999999.99
342
+ When o usuário tenta inserir um valor fora do range
343
+ Then um erro de validação é retornado
344
+
345
+ # ── Permissões ──
346
+
347
+ ${complianceScenario}${domainSpecificSection}
348
+ \`\`\`
349
+
350
+ ---
351
+
352
+ ## Checklist
353
+
354
+ \`\`\`
355
+ □ Cada critério de aceite tem ≥ 1 cenário
356
+ □ Happy path coberto
357
+ □ Error paths cobertos
358
+ □ Edge cases cobertos
359
+ □ Permissões/autenticação cobertos
360
+ □ Cenários são independentes entre si
361
+ \`\`\`
362
+ `;
363
+ }
364
+
365
+ /**
366
+ * Generate TDD template with optional pre-filled examples
367
+ */
368
+ export function generateTddTemplate(ctx?: EnrichedTemplateContext | TemplateContext): string {
369
+ const enriched = getEnriched(ctx);
370
+ const modules = enriched.modules || [];
371
+ const endpoints = enriched.endpoints || [];
372
+ const stack = ctx && 'stack' in ctx ? ctx.stack : undefined;
373
+
374
+ let testFramework = 'jest';
375
+ let exampleTest = ` it('should [resultado esperado] when [condição]', () => {
376
+ // Arrange
377
+ const input = ...;
378
+
379
+ // Act
380
+ const result = metodo(input);
381
+
382
+ // Assert
383
+ expect(result).toEqual(expected);
384
+ });`;
385
+
386
+ // Detect test framework from stack (case-insensitive comparison)
387
+ if (stack) {
388
+ const langs = stack.languages.map((l) => l.toLowerCase());
389
+ if (langs.includes('python')) {
390
+ testFramework = 'pytest';
391
+ } else if (langs.includes('dart')) {
392
+ testFramework = 'flutter_test';
393
+ } else if (langs.includes('java') || langs.includes('kotlin')) {
394
+ testFramework = 'junit';
395
+ } else if (langs.includes('go')) {
396
+ testFramework = 'go_test';
397
+ } else if (langs.includes('rust')) {
398
+ testFramework = 'cargo_test';
399
+ }
400
+ }
401
+
402
+ let moduleName = '[Nome do Módulo/Classe]';
403
+ let methodName = '[método/função]';
404
+ let exampleModule = modules[0];
405
+
406
+ if (exampleModule) {
407
+ moduleName = exampleModule.name;
408
+ const service = exampleModule.services[0] || 'Service';
409
+ methodName = `create${service.replace('Service', '')}`;
410
+
411
+ if (testFramework === 'pytest') {
412
+ exampleTest = ` def test_should_create_entity_successfully(self):
413
+ # Arrange
414
+ input_data = {"name": "Test Entity"}
415
+
416
+ # Act
417
+ result = service.${methodName}(input_data)
418
+
419
+ # Assert
420
+ assert result is not None
421
+ assert result.name == "Test Entity"`;
422
+ } else if (testFramework === 'flutter_test') {
423
+ exampleTest = ` test('should create entity successfully', () async {
424
+ // Arrange
425
+ final input = CreateRequest(name: 'Test');
426
+
427
+ // Act
428
+ final result = await service.${methodName}(input);
429
+
430
+ // Assert
431
+ expect(result, isNotNull);
432
+ expect(result.name, equals('Test'));
433
+ });`;
434
+ } else if (testFramework === 'go_test') {
435
+ exampleTest = `func TestShould_Create${moduleName}_Successfully(t *testing.T) {
436
+ // Arrange
437
+ input := ${moduleName}Input{Name: "Test Entity"}
438
+
439
+ // Act
440
+ result, err := service.${methodName}(input)
441
+
442
+ // Assert
443
+ assert.NoError(t, err)
444
+ assert.NotNil(t, result)
445
+ assert.Equal(t, "Test Entity", result.Name)
446
+ }`;
447
+ } else if (testFramework === 'cargo_test') {
448
+ exampleTest = `#[test]
449
+ fn test_should_create_${moduleName.toLowerCase()}_successfully() {
450
+ // Arrange
451
+ let input = ${moduleName}Input { name: "Test Entity".to_string() };
452
+
453
+ // Act
454
+ let result = service.${methodName}(&input);
455
+
456
+ // Assert
457
+ assert!(result.is_ok());
458
+ assert_eq!(result.unwrap().name, "Test Entity");
459
+ }`;
460
+ } else if (testFramework === 'junit') {
461
+ exampleTest = ` @Test
462
+ void shouldCreate${moduleName}Successfully() {
463
+ // Arrange
464
+ var input = new ${moduleName}Input("Test Entity");
465
+
466
+ // Act
467
+ var result = service.${methodName}(input);
468
+
469
+ // Assert
470
+ assertNotNull(result);
471
+ assertEquals("Test Entity", result.getName());
472
+ }`;
473
+ } else {
474
+ exampleTest = ` it('should create ${moduleName} successfully', () => {
475
+ // Arrange
476
+ const input = { name: 'Test Entity' };
477
+
478
+ // Act
479
+ const result = service.${methodName}(input);
480
+
481
+ // Assert
482
+ expect(result).toBeDefined();
483
+ expect(result.name).toBe('Test Entity');
484
+ });`;
485
+ }
486
+ }
487
+
488
+ let endpointTest = '';
489
+ if (endpoints.length > 0) {
490
+ const endpoint = endpoints[0];
491
+ if (testFramework === 'pytest') {
492
+ endpointTest = `
493
+
494
+ def test_${endpoint.method.toLowerCase()}_${endpoint.path.replace(/\//g, '_')}():
495
+ """Test ${endpoint.method} ${endpoint.path}"""
496
+ # Arrange
497
+ client = TestClient(app)
498
+
499
+ # Act
500
+ response = client.${endpoint.method.toLowerCase()}("${endpoint.path}")
501
+
502
+ # Assert
503
+ assert response.status_code == 200`;
504
+ } else if (testFramework === 'flutter_test') {
505
+ endpointTest = `
506
+
507
+ testWidgets('should ${endpoint.method.toLowerCase()} ${endpoint.path} correctly', (WidgetTester tester) async {
508
+ // Arrange
509
+ when(mockClient.${endpoint.method.toLowerCase()}(endpoint)).thenAnswer((_) async => Response('{}', 200));
510
+
511
+ // Act
512
+ final result = await client.${endpoint.method.toLowerCase()}(endpoint);
513
+
514
+ // Assert
515
+ expect(result.statusCode, equals(200));
516
+ });`;
517
+ } else if (testFramework === 'go_test') {
518
+ endpointTest = `
519
+
520
+ func Test_${endpoint.method}_${endpoint.path.replace(/\//g, '_')}(t *testing.T) {
521
+ // Arrange
522
+ req := httptest.NewRequest("${endpoint.method}", "${endpoint.path}", nil)
523
+ w := httptest.NewRecorder()
524
+
525
+ // Act
526
+ handler.ServeHTTP(w, req)
527
+
528
+ // Assert
529
+ assert.Equal(t, http.StatusOK, w.Code)
530
+ }`;
531
+ } else if (testFramework === 'cargo_test') {
532
+ endpointTest = `
533
+
534
+ #[actix_web::test]
535
+ async fn test_${endpoint.method.toLowerCase()}_${endpoint.path.replace(/\//g, '_')}() {
536
+ // Arrange
537
+ let app = test::init_service(App::new().configure(routes)).await;
538
+ let req = test::TestRequest::${endpoint.method.toLowerCase()}().uri("${endpoint.path}").to_request();
539
+
540
+ // Act
541
+ let resp = test::call_service(&app, req).await;
542
+
543
+ // Assert
544
+ assert!(resp.status().is_success());
545
+ }`;
546
+ } else if (testFramework === 'junit') {
547
+ endpointTest = `
548
+
549
+ @Test
550
+ void should${endpoint.method}${endpoint.handler}Correctly() throws Exception {
551
+ // Act & Assert
552
+ mockMvc.perform(${endpoint.method.toLowerCase()}("${endpoint.path}"))
553
+ .andExpect(status().isOk());
554
+ }`;
555
+ } else {
556
+ endpointTest = `
557
+
558
+ it('should ${endpoint.method.toLowerCase()} ${endpoint.path} correctly', async () => {
559
+ // Arrange
560
+ const endpoint = '${endpoint.path}';
561
+
562
+ // Act
563
+ const response = await request(app).${endpoint.method.toLowerCase()}(endpoint);
564
+
565
+ // Assert
566
+ expect(response.status).toBe(200);
567
+ });`;
568
+ }
569
+ }
570
+
571
+ // @ts-ignore - Audit cleanup unused variable
572
+ const structureLabel = testFramework === 'pytest' ? 'def test_' : testFramework === 'flutter_test' ? 'test(' : 'describe(';
573
+ // @ts-ignore - Audit cleanup unused variable
574
+ const openingBracket = testFramework === 'pytest' ? ':' : testFramework === 'flutter_test' ? ', () async {' : ", () => {";
575
+
576
+ return `# 🔬 Template: TDD — Test-Driven Development
577
+
578
+ > RED → GREEN → REFACTOR. Nesta ordem. Sempre.
579
+
580
+ ---
581
+
582
+ ## Estrutura de Testes (${testFramework})
583
+
584
+ \`\`\`${testFramework === 'pytest' ? 'python' : testFramework === 'flutter_test' ? 'dart' : testFramework === 'go_test' ? 'go' : testFramework === 'cargo_test' ? 'rust' : testFramework === 'junit' ? 'java' : 'typescript'}
585
+ ${
586
+ testFramework === 'pytest'
587
+ ? `import pytest
588
+ from app.services.${moduleName.toLowerCase()} import ${moduleName}Service
589
+
590
+ class Test${moduleName}:
591
+ """Testes para ${moduleName}"""
592
+
593
+ ${exampleTest}
594
+
595
+ def test_should_throw_error_when_invalid_input(self):
596
+ # Arrange
597
+ invalid_input = None
598
+
599
+ # Act & Assert
600
+ with pytest.raises(ValueError):
601
+ service.${methodName}(invalid_input)`
602
+ : testFramework === 'flutter_test'
603
+ ? `import 'package:flutter_test/flutter_test.dart';
604
+ import 'package:${moduleName.toLowerCase()}/services/${moduleName.toLowerCase()}_service.dart';
605
+
606
+ void main() {
607
+ group('${moduleName}Service', () {
608
+
609
+ ${exampleTest}
610
+
611
+ test('should throw exception when input is invalid', () {
612
+ // Arrange
613
+ final invalid = null;
614
+
615
+ // Act & Assert
616
+ expect(() => service.${methodName}(invalid), throwsException);
617
+ });${endpointTest}
618
+ });
619
+ }`
620
+ : testFramework === 'go_test'
621
+ ? `package ${moduleName.toLowerCase()}_test
622
+
623
+ import (
624
+ "testing"
625
+ "net/http"
626
+ "net/http/httptest"
627
+ "github.com/stretchr/testify/assert"
628
+ )
629
+
630
+ // ── Happy Path ──
631
+ ${exampleTest}
632
+
633
+ // ── Error Path ──
634
+ func TestShould_Return_Error_When_InvalidInput(t *testing.T) {
635
+ // Arrange
636
+ input := ${moduleName}Input{}
637
+
638
+ // Act
639
+ _, err := service.${methodName}(input)
640
+
641
+ // Assert
642
+ assert.Error(t, err)
643
+ }${endpointTest}`
644
+ : testFramework === 'cargo_test'
645
+ ? `#[cfg(test)]
646
+ mod tests {
647
+ use super::*;
648
+
649
+ // ── Happy Path ──
650
+ ${exampleTest}
651
+
652
+ // ── Error Path ──
653
+ #[test]
654
+ fn test_should_return_error_when_invalid_input() {
655
+ // Arrange
656
+ let input = ${moduleName}Input { name: "".to_string() };
657
+
658
+ // Act
659
+ let result = service.${methodName}(&input);
660
+
661
+ // Assert
662
+ assert!(result.is_err());
663
+ }${endpointTest}
664
+ }`
665
+ : testFramework === 'junit'
666
+ ? `import org.junit.jupiter.api.Test;
667
+ import static org.junit.jupiter.api.Assertions.*;
668
+
669
+ class ${moduleName}Test {
670
+
671
+ // ── Happy Path ──
672
+ ${exampleTest}
673
+
674
+ // ── Error Path ──
675
+ @Test
676
+ void shouldThrowWhenInvalidInput() {
677
+ // Arrange
678
+ var invalidInput = new ${moduleName}Input(null);
679
+
680
+ // Act & Assert
681
+ assertThrows(IllegalArgumentException.class,
682
+ () -> service.${methodName}(invalidInput));
683
+ }${endpointTest}
684
+ }`
685
+ : `describe('${moduleName}', () => {
686
+
687
+ describe('${methodName}', () => {
688
+
689
+ // ── Happy Path ──
690
+ ${exampleTest}
691
+
692
+ // ── Error Path ──
693
+ it('should throw [erro] when [condição inválida]', () => {
694
+ // Arrange
695
+ const invalidInput = undefined;
696
+
697
+ // Act & Assert
698
+ expect(() => service.${methodName}(invalidInput)).toThrow(Error);
699
+ });
700
+
701
+ // ── Boundary ──
702
+ it('should handle empty input', () => {
703
+ // Arrange
704
+ const boundaryInput = {};
705
+
706
+ // Act
707
+ const result = service.${methodName}(boundaryInput);
708
+
709
+ // Assert
710
+ expect(result).toBeDefined();
711
+ });${endpointTest}
712
+ });
713
+ });`
714
+ }
715
+ \`\`\`
716
+
717
+ ---
718
+
719
+ ## Ciclo TDD
720
+
721
+ \`\`\`
722
+ 1. RED: Escrever teste que FALHA
723
+ 2. GREEN: Escrever código MÍNIMO para passar
724
+ 3. REFACTOR: Melhorar sem quebrar testes
725
+ 4. REPEAT
726
+ \`\`\`
727
+
728
+ ---
729
+
730
+ ## Checklist
731
+
732
+ \`\`\`
733
+ □ Teste escrito ANTES do código
734
+ □ Teste falha antes da implementação (RED)
735
+ □ Implementação mínima para passar (GREEN)
736
+ □ Refatoração sem quebrar testes (REFACTOR)
737
+ □ Happy path coberto
738
+ □ Error path coberto
739
+ □ Boundary cases cobertos
740
+ □ Cobertura atinge o mínimo do projeto
741
+ \`\`\`
742
+ `;
743
+ }
744
+
745
+ /**
746
+ * Generate ADR template with optional pre-filled examples from tech stack
747
+ */
748
+ export function generateAdrTemplate(ctx?: EnrichedTemplateContext | TemplateContext): string {
749
+ const enriched = getEnriched(ctx);
750
+ const stack = ctx && 'stack' in ctx ? ctx.stack : undefined;
751
+ const domain = enriched.domain;
752
+
753
+ let exampleDecision = '[Título da Decisão]';
754
+ let contextDescription = '[descrever o contexto de negócio e técnico]';
755
+ let decisionDescription = '[descrever a decisão claramente]';
756
+ let alternativeOne = '[alternativa 1]';
757
+ let alternativeTwo = '[alternativa 2]';
758
+
759
+ // Generate tech stack specific examples (framework-aware)
760
+ if (stack) {
761
+ const framework = stack.frameworks[0] || 'Backend Framework';
762
+ const database = stack.frameworks.find((f) => ['PostgreSQL', 'MongoDB', 'MySQL', 'SQLite', 'Redis'].includes(f)) || 'PostgreSQL';
763
+ const adrLangs = stack.languages.map((l) => l.toLowerCase());
764
+ const adrIsPython = adrLangs.includes('python');
765
+ const adrIsDart = adrLangs.includes('dart');
766
+ const adrIsGo = adrLangs.includes('go');
767
+ const adrIsJava = adrLangs.includes('java') || adrLangs.includes('kotlin');
768
+
769
+ exampleDecision = `Uso de ${framework} para Backend`;
770
+
771
+ if (adrIsPython) {
772
+ contextDescription = `O projeto requer uma API REST escalável com Python. Precisamos escolher um framework que:
773
+ - Suporte async/await nativo
774
+ - Tenha tipagem com Pydantic e validação automática
775
+ - Tenha comunidade ativa e documentação excelente`;
776
+ decisionDescription = `Decidimos usar ${framework} como framework backend principal. ${framework} oferece:
777
+ - Async/await nativo com alto desempenho
778
+ - Validação automática via Pydantic
779
+ - Documentação OpenAPI/Swagger automática
780
+ - Suporte a bancos de dados (SQLAlchemy, Tortoise ORM, etc.)`;
781
+ alternativeOne = 'Django REST Framework';
782
+ alternativeTwo = 'Flask + extensões';
783
+ } else if (adrIsDart) {
784
+ contextDescription = `O projeto requer um aplicativo mobile multiplataforma. Precisamos escolher um framework que:
785
+ - Suporte iOS e Android com um único codebase
786
+ - Tenha hot-reload e boa experiência de desenvolvimento
787
+ - Tenha widgets nativos e alta performance`;
788
+ decisionDescription = `Decidimos usar ${framework} como framework principal. ${framework} oferece:
789
+ - UI declarativa com widgets nativos
790
+ - Hot-reload para desenvolvimento rápido
791
+ - Compilação nativa para iOS e Android
792
+ - Ecossistema de pacotes via pub.dev`;
793
+ alternativeOne = 'React Native';
794
+ alternativeTwo = 'Kotlin Multiplatform';
795
+ } else if (adrIsGo) {
796
+ contextDescription = `O projeto requer um serviço backend de alta performance. Precisamos escolher uma stack que:
797
+ - Tenha concorrência nativa eficiente
798
+ - Suporte compilação estática e deploy simplificado
799
+ - Tenha forte tipagem e performance previsível`;
800
+ decisionDescription = `Decidimos usar ${framework} como framework principal. ${framework} oferece:
801
+ - Goroutines para concorrência eficiente
802
+ - Binário estático único para deploy
803
+ - Performance previsível e baixo footprint
804
+ - Ecossistema robusto de middleware`;
805
+ alternativeOne = 'net/http padrão + chi router';
806
+ alternativeTwo = 'Fiber (Express-like para Go)';
807
+ } else if (adrIsJava) {
808
+ contextDescription = `O projeto requer uma API REST enterprise-grade. Precisamos escolher um framework que:
809
+ - Suporte injeção de dependência nativa
810
+ - Tenha ecossistema maduro e produção comprovada
811
+ - Tenha integração com bancos de dados (JPA/Hibernate)`;
812
+ decisionDescription = `Decidimos usar ${framework} como framework backend principal. ${framework} oferece:
813
+ - Injeção de dependência nativa
814
+ - Ecossistema maduro com milhares de extensões
815
+ - Suporte a JPA/Hibernate para persistência
816
+ - Segurança via Spring Security / equivalente`;
817
+ alternativeOne = 'Quarkus (nativo GraalVM)';
818
+ alternativeTwo = 'Micronaut';
819
+ } else {
820
+ contextDescription = `O projeto requer uma API REST escalável com TypeScript. Precisamos escolher um framework que:
821
+ - Suporte TypeScript nativo
822
+ - Tenha decorators e dependency injection
823
+ - Tenha comunidade ativa e documentação excelente`;
824
+ decisionDescription = `Decidimos usar ${framework} como framework backend principal. ${framework} oferece:
825
+ - Arquitetura modular built-in
826
+ - Decorators para roteamento e middleware
827
+ - Injeção de dependência nativa
828
+ - Suporte a bancos de dados (TypeORM, Prisma, etc.)`;
829
+ alternativeOne = 'Express.js + middleware customizado';
830
+ alternativeTwo = 'Fastify';
831
+ }
832
+
833
+ // Add database-specific ADR if applicable
834
+ let dbDecision = '';
835
+ if (database) {
836
+ dbDecision = `
837
+
838
+ ---
839
+
840
+ ## ADR-002: Banco de Dados ${database}
841
+
842
+ **Status:** accepted
843
+ **Data:** 2024-01-15
844
+ **Autores:** [equipe técnica]
845
+
846
+ ### Contexto
847
+
848
+ Precisamos escolher um banco de dados relacional que:
849
+ - Suporte transações ACID
850
+ - Tenha integração com ${framework}
851
+ - Permita escalabilidade horizontal
852
+
853
+ ### Decisão
854
+
855
+ Escolhemos ${database} como banco de dados principal por:
856
+ - Suporte a JSON nativo
857
+ - Excelente performance em leitura/escrita
858
+ - Integração com ${adrIsPython ? 'SQLAlchemy/Alembic' : adrIsJava ? 'JPA/Hibernate' : adrIsGo ? 'GORM/sqlx' : 'TypeORM/Prisma'} é padrão
859
+
860
+ ### Alternativas Consideradas
861
+
862
+ | # | Alternativa | Prós | Contras |
863
+ |---|-----------|------|---------|
864
+ | 1 | MySQL | Popular, estável | Menos recursos avançados |
865
+ | 2 | MongoDB | Escalável | Sem ACID nativo, schema dinâmico |`;
866
+ return `# 📋 Template: ADR — Architecture Decision Record
867
+
868
+ > Use quando uma decisão técnica é significativa ou controversa.
869
+
870
+ ---
871
+
872
+ ## ADR-001: ${exampleDecision}
873
+
874
+ **Status:** proposed | accepted | deprecated | superseded by ADR-YYY
875
+ **Data:** YYYY-MM-DD
876
+ **Autores:** [quem participou da decisão]
877
+
878
+ ---
879
+
880
+ ### Contexto
881
+
882
+ > Qual é o problema ou necessidade que levou a esta decisão?
883
+
884
+ ${contextDescription}
885
+
886
+ ---
887
+
888
+ ### Decisão
889
+
890
+ > O que foi decidido?
891
+
892
+ ${decisionDescription}
893
+
894
+ ---
895
+
896
+ ### Alternativas Consideradas
897
+
898
+ | # | Alternativa | Prós | Contras | Por que descartada |
899
+ |---|-----------|------|---------|-------------------|
900
+ | 1 | ${alternativeOne} | [prós] | [contras] | [motivo] |
901
+ | 2 | ${alternativeTwo} | [prós] | [contras] | [motivo] |
902
+
903
+ ---
904
+
905
+ ### Consequências
906
+
907
+ **Positivas:**
908
+ - Arquitetura clara e escalável
909
+ - Código mais organizado e testável
910
+ - Comunidade ativa para suporte
911
+
912
+ **Negativas:**
913
+ - Curva de aprendizado para novos desenvolvedores
914
+ - Overhead de dependências
915
+
916
+ **Riscos:**
917
+ - Atualização de versões major — probabilidade: média
918
+
919
+ ---
920
+
921
+ ### Notas
922
+
923
+ - Revisar em 6 meses se a decisão continua válida
924
+ ${dbDecision}`;
925
+ }
926
+ }
927
+
928
+ // Add domain-specific ADR section
929
+ let domainAdrs = '';
930
+ if (domain?.domain === 'fintech') {
931
+ domainAdrs = `
932
+
933
+ ---
934
+
935
+ ## ADR-XXX: Criptografia de CPF e Dados Sensíveis
936
+
937
+ **Status:** proposed
938
+ **Data:** YYYY-MM-DD
939
+ **Autores:** [equipe de segurança]
940
+
941
+ ### Contexto
942
+
943
+ Dados de clientes (CPF, CNPJ, dados bancários) são críticos para fintech.
944
+ Precisamos de criptografia de dados sensíveis at-rest.
945
+
946
+ ### Decisão
947
+
948
+ Usar AES-256 para criptografia de dados sensíveis com chaves armazenadas no vault.
949
+
950
+ ### Alternativas Consideradas
951
+
952
+ | # | Alternativa | Segurança | Complexidade |
953
+ |---|-----------|----------|--------------|
954
+ | 1 | AES-256 | Alta | Média |
955
+ | 2 | RSA | Muito Alta | Alta |
956
+ | 3 | Nenhuma | Baixa | Baixa |`;
957
+ } else if (domain?.domain === 'healthtech') {
958
+ domainAdrs = `
959
+
960
+ ---
961
+
962
+ ## ADR-XXX: Conformidade HIPAA em Armazenamento
963
+
964
+ **Status:** proposed
965
+ **Data:** YYYY-MM-DD
966
+ **Autores:** [equipe de compliance]
967
+
968
+ ### Contexto
969
+
970
+ Dados de saúde devem estar em conformidade com HIPAA.
971
+ Precisamos garantir criptografia, auditoria e retenção apropriada.
972
+
973
+ ### Decisão
974
+
975
+ Implementar criptografia AES-256, logging de acesso e retenção de dados por 7 anos.`;
976
+ }
977
+
978
+ return `# 📋 Template: ADR — Architecture Decision Record
979
+
980
+ > Use quando uma decisão técnica é significativa ou controversa.
981
+
982
+ ---
983
+
984
+ ## ADR-XXX: ${exampleDecision}
985
+
986
+ **Status:** proposed | accepted | deprecated | superseded by ADR-YYY
987
+ **Data:** YYYY-MM-DD
988
+ **Autores:** [quem participou da decisão]
989
+
990
+ ---
991
+
992
+ ### Contexto
993
+
994
+ > Qual é o problema ou necessidade que levou a esta decisão?
995
+
996
+ ${contextDescription}
997
+
998
+ ---
999
+
1000
+ ### Decisão
1001
+
1002
+ > O que foi decidido?
1003
+
1004
+ ${decisionDescription}
1005
+
1006
+ ---
1007
+
1008
+ ### Alternativas Consideradas
1009
+
1010
+ | # | Alternativa | Prós | Contras | Por que descartada |
1011
+ |---|-----------|------|---------|-------------------|
1012
+ | 1 | ${alternativeOne} | [prós] | [contras] | [motivo] |
1013
+ | 2 | ${alternativeTwo} | [prós] | [contras] | [motivo] |
1014
+
1015
+ ---
1016
+
1017
+ ### Consequências
1018
+
1019
+ **Positivas:**
1020
+ - [consequência positiva 1]
1021
+ - [consequência positiva 2]
1022
+
1023
+ **Negativas:**
1024
+ - [consequência negativa 1]
1025
+ - [mitigação: como minimizar]
1026
+
1027
+ **Riscos:**
1028
+ - [risco 1] — probabilidade: [alta/média/baixa]
1029
+
1030
+ ---
1031
+
1032
+ ### Notas
1033
+
1034
+ - [qualquer informação adicional]${domainAdrs}
1035
+ `;
1036
+ }
1037
+
1038
+ /**
1039
+ * Generate Threat Model template with optional pre-filled domain-specific threats
1040
+ */
1041
+ export function generateThreatModelTemplate(ctx?: EnrichedTemplateContext | TemplateContext): string {
1042
+ const enriched = getEnriched(ctx);
1043
+ const domain = enriched.domain;
1044
+ // @ts-ignore - Audit cleanup unused variable
1045
+ const businessEntities = domain?.businessEntities || [];
1046
+ const compliance = domain?.compliance || [];
1047
+
1048
+ let featureName = '[Nome]';
1049
+ let actors = `| [ator 1] | [alto/médio/baixo] | [dados/recursos] |`;
1050
+ let sensitiveData = `| [dado 1] | PII / Financeiro / Auth | [como proteger] |`;
1051
+ let domainSpecificThreats = '';
1052
+
1053
+ // Generate domain-specific actors and threats
1054
+ if (domain?.domain === 'fintech') {
1055
+ featureName = 'Transferência Bancária';
1056
+ actors = `| Usuário | Alto | Conta bancária, saldo |
1057
+ | Sistema Interno | Alto | Todas as transações |
1058
+ | Banco Parceiro | Médio | Dados de rota |
1059
+ | Auditor (interno) | Médio | Logs de transações |`;
1060
+
1061
+ sensitiveData = `| CPF | PII | AES-256 at-rest, TLS in-transit |
1062
+ | Número de Conta | Financeiro | AES-256 + masking |
1063
+ | Saldo | Financeiro | Hash verificável |
1064
+ | Histórico de Transações | Auditoria | Criptografado, signed |`;
1065
+
1066
+ domainSpecificThreats = `
1067
+
1068
+ ---
1069
+
1070
+ ## Ameaças Específicas de Fintech
1071
+
1072
+ | Ameaça | Descrição | Mitigação |
1073
+ |--------|-----------|-----------|
1074
+ | Falsificação de Identidade | Hacker usa CPF falso para abrir conta | Validação com gov API, SMS 2FA |
1075
+ | Tamperização de Saldo | Atacante modifica saldo direto no DB | Checksums, transações com assinatura |
1076
+ | Roubo de Sessão | Hijack de cookie de autenticação | HTTPS, SameSite cookie, token rotation |
1077
+ | Negação de Transferência | Usuário nega ter feito transação | Auditoria, e-mail de confirmação |
1078
+ | Bloqueio de Serviço | DDoS na API de transações | Rate limiting, WAF, CDN |
1079
+ | Escalonamento de Permissão | Admin faz transferência não autorizada | RBAC, audit logging, segregação |`;
1080
+ } else if (domain?.domain === 'tax' || domain?.subDomain === 'tax-processing') {
1081
+ featureName = 'Cálculo e Envio de Imposto';
1082
+ actors = `| Contribuinte | Alto | Declaração, CPF, rendimentos |
1083
+ | Contador | Médio | Dados do cliente, acesso a declaração |
1084
+ | Receita Federal | Médio | Declaração enviada, comprovantes |
1085
+ | Auditor Interno | Médio | Logs de processamento, erros |`;
1086
+
1087
+ sensitiveData = `| CPF/CNPJ | PII | AES-256, masking em logs |
1088
+ | Rendimentos Totais | Financeiro | Criptografado |
1089
+ | Deduções e Benefícios | Pessoal | Criptografado |
1090
+ | Histórico de Envios | Auditoria | Signed, imutável |`;
1091
+
1092
+ domainSpecificThreats = `
1093
+
1094
+ ---
1095
+
1096
+ ## Ameaças Específicas de Impostos
1097
+
1098
+ | Ameaça | Descrição | Mitigação |
1099
+ |--------|-----------|-----------|
1100
+ | Falsificação de Receita | Declarar rendimento falso | Cruzamento com dados da Receita Federal |
1101
+ | Tamperização de Cálculo | Hacker reduz imposto devido | Validação automática, recálculo periódico |
1102
+ | Vazamento de Dados | Exposição de CPF/rendimento | Criptografia, LGPD compliance |
1103
+ | Negação de Envio | Usuário nega envio ao fisco | Timestamp assinado, audit log |
1104
+ | Indisponibilidade na Época | Servidor cai no último dia | SLA 99.9%, failover automático |
1105
+ | Acesso não Autorizado | Contador acessa dado de cliente errado | RBAC granular, segregação de dados |`;
1106
+ } else if (domain?.domain === 'healthtech') {
1107
+ featureName = 'Acesso a Histórico Médico';
1108
+ actors = `| Paciente | Alto | Histórico médico, exames, receitas |
1109
+ | Médico | Alto | Prontuário do paciente |
1110
+ | Farmacêutico | Médio | Prescrições, alergias |
1111
+ | Auditor Compliance | Médio | Logs de acesso, consentimento |`;
1112
+
1113
+ sensitiveData = `| Nome Paciente | PII | Criptografado, HIPAA compliant |
1114
+ | Histórico Médico | Saúde | AES-256, acesso restrito |
1115
+ | Medicamentos | Saúde | Criptografado, masking em logs |
1116
+ | Resultado de Exames | Saúde | Criptografado, assinado digitalmente |`;
1117
+
1118
+ domainSpecificThreats = `
1119
+
1120
+ ---
1121
+
1122
+ ## Ameaças Específicas de Healthtech
1123
+
1124
+ | Ameaça | Descrição | Mitigação |
1125
+ |--------|-----------|-----------|
1126
+ | Acesso não Autorizado | Outro médico lê prontuário | RBAC por especialidade, audit |
1127
+ | Adulteração de Histórico | Alterar resultado de exame | Blockchain/assinatura digital |
1128
+ | Vazamento de Dados | Exposição de histórico médico | Criptografia, isolamento de rede |
1129
+ | Negação de Diagnóstico | Paciente nega consentimento | Digital signature + timestamp |
1130
+ | Indisponibilidade | Sistema cai durante consulta | Backup em tempo real, SLA 99.95% |
1131
+ | Privilégio Elevado | Admin lê dados de qualquer paciente | Segregação de funções, logging |`;
1132
+ }
1133
+
1134
+ return `# 🛡️ Template: Threat Model (STRIDE)
1135
+
1136
+ > Use para features que lidam com dados sensíveis, pagamentos, autenticação.
1137
+
1138
+ ---
1139
+
1140
+ ## Feature: ${featureName}
1141
+
1142
+ ### Atores e Assets
1143
+
1144
+ | Ator | Nível de Confiança | Assets que Acessa |
1145
+ |------|-------------------|------------------|
1146
+ ${actors}
1147
+
1148
+ ---
1149
+
1150
+ ### Análise STRIDE
1151
+
1152
+ | Categoria | Ameaça | Probabilidade | Impacto | Mitigação |
1153
+ |-----------|--------|-------------|---------|-----------|
1154
+ | **S**poofing | Identidade falsa / autenticação fraca | M | A | MFA, JWT assinado, validação gov |
1155
+ | **T**ampering | Alteração de dados em trânsito/repouso | M | A | HTTPS, assinatura digital, checksums |
1156
+ | **R**epudiation | Negar ação realizada | M | A | Audit log detalhado com timestamp |
1157
+ | **I**nformation Disclosure | Vazamento de dados sensíveis | A | A | Criptografia AES-256, LGPD compliance |
1158
+ | **D**enial of Service | Serviço indisponível (DDoS, travamento) | M | A | Rate limiting, WAF, scaling automático |
1159
+ | **E**levation of Privilege | Escalar permissão (user → admin) | M | A | RBAC granular, segregação de funções |
1160
+
1161
+ ---
1162
+
1163
+ ### Dados Sensíveis
1164
+
1165
+ | Dado | Classificação | Proteção |
1166
+ |------|-------------|----------|
1167
+ ${sensitiveData}
1168
+
1169
+ ---
1170
+
1171
+ ### Conformidade e Requisitos Regulatórios
1172
+
1173
+ ${
1174
+ compliance.length > 0
1175
+ ? `| Regulamento | Aplicável | Verificação |
1176
+ |-------------|-----------|-------------|
1177
+ ${compliance.map((c) => `| ${c.name} | Sim | ${c.mandatoryChecks[0] || 'Auditoria'} |`).join('\n')}`
1178
+ : `| Regulamento | Aplicável | Verificação |
1179
+ |-------------|-----------|-------------|
1180
+ | LGPD (dados pessoais) | Depende | Consentimento, direito ao esquecimento |
1181
+ | Conformidade de Dados | Depende | Criptografia, HTTPS, audit logs |`
1182
+ }
1183
+
1184
+ ---
1185
+
1186
+ ### Checklist de Segurança
1187
+
1188
+ \`\`\`
1189
+ □ Input validado e sanitizado
1190
+ □ Output encodado (XSS prevention)
1191
+ □ Queries parametrizadas (SQL injection)
1192
+ □ Autenticação obrigatória (MFA quando sensível)
1193
+ □ Autorização por role/permission (RBAC)
1194
+ □ Dados sensíveis criptografados at rest (AES-256)
1195
+ □ Dados sensíveis criptografados in transit (TLS 1.2+)
1196
+ □ Rate limiting implementado
1197
+ □ Audit log para ações sensíveis (timestamp + usuário)
1198
+ □ Secrets em variáveis de ambiente (não hardcoded)
1199
+ □ Consentimento e transparência (LGPD/GDPR)
1200
+ □ Testes de penetração agendados
1201
+ \`\`\`
1202
+ ${domainSpecificThreats}
1203
+ `;
1204
+ }