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