eva4j 1.0.14 → 1.0.16

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 (139) hide show
  1. package/.agents/skills/skill-creator/LICENSE.txt +202 -0
  2. package/.agents/skills/skill-creator/SKILL.md +485 -0
  3. package/.agents/skills/skill-creator/agents/analyzer.md +274 -0
  4. package/.agents/skills/skill-creator/agents/comparator.md +202 -0
  5. package/.agents/skills/skill-creator/agents/grader.md +223 -0
  6. package/.agents/skills/skill-creator/assets/eval_review.html +146 -0
  7. package/.agents/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  8. package/.agents/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  9. package/.agents/skills/skill-creator/references/schemas.md +430 -0
  10. package/.agents/skills/skill-creator/scripts/__init__.py +0 -0
  11. package/.agents/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  12. package/.agents/skills/skill-creator/scripts/generate_report.py +326 -0
  13. package/.agents/skills/skill-creator/scripts/improve_description.py +247 -0
  14. package/.agents/skills/skill-creator/scripts/package_skill.py +136 -0
  15. package/.agents/skills/skill-creator/scripts/quick_validate.py +103 -0
  16. package/.agents/skills/skill-creator/scripts/run_eval.py +310 -0
  17. package/.agents/skills/skill-creator/scripts/run_loop.py +328 -0
  18. package/.agents/skills/skill-creator/scripts/utils.py +47 -0
  19. package/AGENTS.md +268 -6
  20. package/COMMAND_EVALUATION.md +15 -16
  21. package/DOMAIN_YAML_GUIDE.md +430 -14
  22. package/FUTURE_FEATURES.md +1627 -1168
  23. package/README.md +461 -13
  24. package/bin/eva4j.js +32 -14
  25. package/config/defaults.json +1 -0
  26. package/docs/commands/EVALUATE_SYSTEM.md +746 -261
  27. package/docs/commands/EXPORT_DIAGRAM.md +153 -0
  28. package/docs/commands/GENERATE_ENTITIES.md +599 -6
  29. package/docs/commands/INDEX.md +7 -0
  30. package/examples/domain-events.yaml +166 -20
  31. package/examples/domain-listeners.yaml +212 -0
  32. package/examples/domain-one-to-many.yaml +1 -0
  33. package/examples/domain-one-to-one.yaml +1 -0
  34. package/examples/domain-ports.yaml +414 -0
  35. package/examples/domain-soft-delete.yaml +47 -44
  36. package/examples/system/notification.yaml +147 -0
  37. package/examples/system/product.yaml +185 -0
  38. package/examples/system/system.yaml +112 -0
  39. package/examples/system-report.html +971 -0
  40. package/examples/system.yaml +46 -3
  41. package/package.json +2 -1
  42. package/src/agents/design-reviewer.agent.md +163 -0
  43. package/src/commands/build.js +714 -0
  44. package/src/commands/create.js +1 -0
  45. package/src/commands/detach.js +149 -108
  46. package/src/commands/evaluate-system.js +234 -8
  47. package/src/commands/export-diagram.js +522 -0
  48. package/src/commands/generate-entities.js +685 -66
  49. package/src/commands/generate-http-exchange.js +2 -0
  50. package/src/commands/generate-kafka-event.js +43 -10
  51. package/src/generators/base-generator.js +18 -6
  52. package/src/generators/postman-generator.js +188 -0
  53. package/src/generators/shared-generator.js +12 -2
  54. package/src/skills/build-system-yaml/SKILL.md +323 -0
  55. package/src/skills/build-system-yaml/references/domain-yaml-spec.md +410 -0
  56. package/src/skills/build-system-yaml/references/module-spec.md +367 -0
  57. package/src/skills/build-system-yaml/references/system-yaml-spec.md +178 -0
  58. package/src/utils/config-manager.js +54 -0
  59. package/src/utils/context-builder.js +1 -0
  60. package/src/utils/domain-diagram.js +192 -0
  61. package/src/utils/domain-validator.js +1020 -0
  62. package/src/utils/fake-data.js +376 -0
  63. package/src/utils/system-validator.js +319 -199
  64. package/src/utils/yaml-to-entity.js +272 -7
  65. package/templates/aggregate/AggregateMapper.java.ejs +3 -2
  66. package/templates/aggregate/AggregateRepository.java.ejs +3 -2
  67. package/templates/aggregate/AggregateRepositoryImpl.java.ejs +6 -5
  68. package/templates/aggregate/AggregateRoot.java.ejs +60 -2
  69. package/templates/aggregate/DomainEventHandler.java.ejs +4 -1
  70. package/templates/aggregate/DomainEventRecord.java.ejs +24 -8
  71. package/templates/aggregate/DomainEventSnapshot.java.ejs +46 -0
  72. package/templates/aggregate/JpaAggregateRoot.java.ejs +6 -0
  73. package/templates/base/docker/Dockerfile.ejs +21 -0
  74. package/templates/base/gradle/build.gradle.ejs +3 -2
  75. package/templates/base/root/AGENTS.md.ejs +306 -45
  76. package/templates/crud/ApplicationMapper.java.ejs +4 -0
  77. package/templates/crud/Controller.java.ejs +4 -4
  78. package/templates/crud/CreateCommand.java.ejs +4 -0
  79. package/templates/crud/CreateCommandHandler.java.ejs +3 -6
  80. package/templates/crud/CreateItemDto.java.ejs +4 -0
  81. package/templates/crud/CreateValueObjectDto.java.ejs +4 -0
  82. package/templates/crud/DeleteCommandHandler.java.ejs +12 -6
  83. package/templates/crud/EndpointsController.java.ejs +6 -6
  84. package/templates/crud/FindByQuery.java.ejs +1 -1
  85. package/templates/crud/FindByQueryHandler.java.ejs +3 -9
  86. package/templates/crud/GetQueryHandler.java.ejs +2 -5
  87. package/templates/crud/ListQuery.java.ejs +1 -1
  88. package/templates/crud/ListQueryHandler.java.ejs +8 -14
  89. package/templates/crud/ScaffoldCommandHandler.java.ejs +2 -4
  90. package/templates/crud/ScaffoldQuery.java.ejs +3 -2
  91. package/templates/crud/ScaffoldQueryHandler.java.ejs +5 -6
  92. package/templates/crud/SubEntityAddCommand.java.ejs +4 -0
  93. package/templates/crud/SubEntityAddCommandHandler.java.ejs +2 -6
  94. package/templates/crud/SubEntityRemoveCommandHandler.java.ejs +2 -7
  95. package/templates/crud/TransitionCommandHandler.java.ejs +2 -6
  96. package/templates/crud/UpdateCommand.java.ejs +4 -0
  97. package/templates/crud/UpdateCommandHandler.java.ejs +2 -5
  98. package/templates/evaluate/report.html.ejs +394 -2
  99. package/templates/kafka-event/DomainEventHandlerMethod.ejs +3 -1
  100. package/templates/kafka-event/Event.java.ejs +9 -0
  101. package/templates/kafka-listener/KafkaController.java.ejs +1 -1
  102. package/templates/kafka-listener/KafkaListenerClass.java.ejs +1 -1
  103. package/templates/kafka-listener/ListenerClass.java.ejs +65 -0
  104. package/templates/kafka-listener/ListenerCommand.java.ejs +31 -0
  105. package/templates/kafka-listener/ListenerCommandHandler.java.ejs +25 -0
  106. package/templates/kafka-listener/ListenerIntegrationEvent.java.ejs +37 -0
  107. package/templates/kafka-listener/ListenerMethod.java.ejs +1 -1
  108. package/templates/kafka-listener/ListenerNestedType.java.ejs +28 -0
  109. package/templates/mock/MockEvent.java.ejs +10 -0
  110. package/templates/mock/MockMessageBrokerImpl.java.ejs +35 -0
  111. package/templates/mock/MockMessageBrokerImplMethod.java.ejs +6 -0
  112. package/templates/mock/SpringEventListener.java.ejs +61 -0
  113. package/templates/ports/PortDomainModel.java.ejs +35 -0
  114. package/templates/ports/PortFeignAdapter.java.ejs +67 -0
  115. package/templates/ports/PortFeignClient.java.ejs +45 -0
  116. package/templates/ports/PortFeignConfig.java.ejs +24 -0
  117. package/templates/ports/PortInterface.java.ejs +45 -0
  118. package/templates/ports/PortNestedType.java.ejs +28 -0
  119. package/templates/ports/PortRequestDto.java.ejs +30 -0
  120. package/templates/ports/PortResponseDto.java.ejs +28 -0
  121. package/templates/postman/Collection.json.ejs +1 -1
  122. package/templates/postman/UnifiedCollection.json.ejs +185 -0
  123. package/templates/shared/annotations/LogAfter.java.ejs +2 -0
  124. package/templates/shared/annotations/LogBefore.java.ejs +2 -0
  125. package/templates/shared/annotations/LogExceptions.java.ejs +2 -0
  126. package/templates/shared/annotations/LogLevel.java.ejs +8 -0
  127. package/templates/shared/annotations/LogTimer.java.ejs +1 -0
  128. package/templates/shared/annotations/Loggable.java.ejs +17 -0
  129. package/templates/shared/configurations/eventPublicationConfig/EventPublicationSchemaConfig.java.ejs +109 -0
  130. package/templates/shared/configurations/loggerConfig/HandlerLogs.java.ejs +120 -32
  131. package/templates/shared/errorMessage/ErrorResponse.java.ejs +23 -0
  132. package/templates/shared/handlerException/HandlerExceptions.java.ejs +99 -79
  133. package/src/commands/generate-system.js +0 -243
  134. package/templates/base/root/skill-build-domain-yaml-references-generate-entities.md.ejs +0 -1103
  135. package/templates/base/root/skill-build-domain-yaml.ejs +0 -292
  136. package/templates/base/root/skill-build-system-yaml.ejs +0 -252
  137. package/templates/shared/errorMessage/ErrorMessage.java.ejs +0 -5
  138. package/templates/shared/errorMessage/FullErrorMessage.java.ejs +0 -9
  139. package/templates/shared/errorMessage/ShortErrorMessage.java.ejs +0 -6
@@ -206,7 +206,9 @@ integrations:
206
206
  topic: RESERVATION_CREATED
207
207
  consumers:
208
208
  - module: payments
209
+ useCase: HandleReservationCreated
209
210
  - module: notifications
211
+ useCase: NotifyReservationCreated
210
212
 
211
213
  # Pago aprobado → reserva debe confirmarse; cliente recibe confirmación
212
214
  - event: PaymentApprovedEvent
@@ -214,7 +216,9 @@ integrations:
214
216
  topic: PAYMENT_APPROVED
215
217
  consumers:
216
218
  - module: reservations
219
+ useCase: ConfirmReservation
217
220
  - module: notifications
221
+ useCase: NotifyPaymentApproved
218
222
 
219
223
  # Pago rechazado → reserva debe expirar y liberar asientos; cliente recibe aviso
220
224
  - event: PaymentRejectedEvent
@@ -222,22 +226,41 @@ integrations:
222
226
  topic: PAYMENT_REJECTED
223
227
  consumers:
224
228
  - module: reservations
229
+ useCase: ExpireReservation
225
230
  - module: notifications
231
+ useCase: NotifyPaymentRejected
226
232
 
227
- # Reserva confirmada → se emiten los tickets QR y se envían al cliente
233
+ # Reserva confirmada → se emiten los tickets QR y se envían al cliente; cliente acumula puntos de fidelidad
228
234
  - event: ReservationConfirmedEvent
229
235
  producer: reservations
230
236
  topic: RESERVATION_CONFIRMED
231
237
  consumers:
232
238
  - module: notifications
239
+ useCase: NotifyReservationConfirmed
240
+ - module: customers # acumula loyalty points al confirmar reserva
241
+ useCase: AccumulateLoyaltyPoints
233
242
 
234
- # Reserva cancelada → pagos evalúa reembolso; cliente recibe notificación
243
+ # Reserva cancelada → pagos evalúa reembolso; screenings libera asientos; cliente recibe notificación
235
244
  - event: ReservationCancelledEvent
236
245
  producer: reservations
237
246
  topic: RESERVATION_CANCELLED
238
247
  consumers:
239
- - module: payments
248
+ - module: payments # evalúa si aplica reembolso
249
+ useCase: ProcessRefund
250
+ - module: screenings # libera ScreeningSeats → AVAILABLE (también cubre unlock de sala privada)
251
+ useCase: ReleaseScreeningSeats
240
252
  - module: notifications
253
+ useCase: NotifyReservationCancelled
254
+
255
+ # Reserva expirada por timeout (sin pago) → screenings libera asientos; cliente recibe aviso (sin reembolso)
256
+ - event: ReservationExpiredEvent
257
+ producer: reservations
258
+ topic: RESERVATION_EXPIRED
259
+ consumers:
260
+ - module: screenings # libera ScreeningSeats → AVAILABLE
261
+ useCase: ReleaseScreeningSeats
262
+ - module: notifications # avisa al cliente que su tiempo de bloqueo expiró
263
+ useCase: NotifyReservationExpired
241
264
 
242
265
  # Función cancelada → reservas libera asientos y expira reservas activas; clientes notificados
243
266
  - event: ScreeningCancelledEvent
@@ -245,7 +268,9 @@ integrations:
245
268
  topic: SCREENING_CANCELLED
246
269
  consumers:
247
270
  - module: reservations
271
+ useCase: CancelReservationsByScreening
248
272
  - module: notifications
273
+ useCase: NotifyScreeningCancelled
249
274
 
250
275
  # ★ NUEVO — Reserva de evento privado creada → screenings bloquea la sala; payments inicia cobro total; notifications avisa
251
276
  - event: PrivateEventReservationCreatedEvent
@@ -253,8 +278,11 @@ integrations:
253
278
  topic: PRIVATE_EVENT_RESERVATION_CREATED
254
279
  consumers:
255
280
  - module: screenings
281
+ useCase: LockScreeningForPrivateEvent
256
282
  - module: payments
283
+ useCase: InitiatePrivateEventPayment
257
284
  - module: notifications
285
+ useCase: NotifyPrivateEventReservationCreated
258
286
 
259
287
  # ★ NUEVO — Sala bloqueada exitosamente → notifications confirma al organizador del evento
260
288
  - event: TheaterLockedForPrivateEventEvent
@@ -262,8 +290,23 @@ integrations:
262
290
  topic: THEATER_LOCKED_FOR_PRIVATE_EVENT
263
291
  consumers:
264
292
  - module: notifications
293
+ useCase: NotifyTheaterLockedForPrivateEvent
265
294
 
266
295
  sync:
296
+ # Al programar una función se valida que la película esté activa y se obtiene su duración
297
+ - caller: screenings
298
+ calls: movies
299
+ port: MovieService
300
+ using:
301
+ - GET /movies/{id}
302
+
303
+ # Al programar una función se valida que la sala esté activa y se copian los asientos al mapa de la función
304
+ - caller: screenings
305
+ calls: theaters
306
+ port: TheaterService
307
+ using:
308
+ - GET /theaters/{id}
309
+
267
310
  # Al crear una reserva se consulta la función para validar disponibilidad y precio
268
311
  # ★ MODIFICADO — se agrega consulta de disponibilidad para evento privado
269
312
  - caller: reservations
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eva4j",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "description": "A powerful Node.js CLI for generating Spring Boot projects with modular architecture that enables efficient monolith-first development with seamless transition to microservices",
5
5
  "main": "bin/eva4j.js",
6
6
  "bin": {
@@ -41,6 +41,7 @@
41
41
  },
42
42
  "homepage": "https://github.com/asuridev/eva4j#readme",
43
43
  "dependencies": {
44
+ "@faker-js/faker": "^10.3.0",
44
45
  "chalk": "^4.1.2",
45
46
  "clipboardy": "^2.3.0",
46
47
  "commander": "^11.1.0",
@@ -0,0 +1,163 @@
1
+ ---
2
+ name: design-reviewer
3
+ description: "Review, question, and refine an eva4j system design. Use when the user wants to validate design decisions, ask questions about the architecture, adjust domain.yaml or module specifications, add or modify endpoints, events, listeners, ports, or propagate changes across system/ files (system.yaml, module YAML, module MD, C4 diagrams)."
4
+ tools: [read, edit, search]
5
+ argument-hint: "Ask a question about the system design or request a change"
6
+ ---
7
+
8
+ You are two roles simultaneously:
9
+
10
+ 1. **Software Architect** expert in DDD, hexagonal architecture, and CQRS. You understand bounded contexts, aggregate design, event-driven communication, and the eva4j code generation pipeline.
11
+
12
+ 2. **Domain Expert** for the specific business described in the project's design files. You reason about business rules, invariants, entity lifecycles, and user-facing operations as someone who deeply understands the domain.
13
+
14
+ Your job is to help the user **review, question, and refine** an existing system design. You do NOT create designs from scratch — that is the `build-system-yaml` skill's job. You work with designs that already exist in the `system/` directory.
15
+
16
+ ---
17
+
18
+ ## Bootstrap — First Actions on Every Conversation
19
+
20
+ Before answering any question, silently perform these reads:
21
+
22
+ 1. Read `system/system.yaml` — understand modules, endpoints, async events, sync calls
23
+ 2. Read `system/system.md` — understand the narrative specification
24
+ 3. Identify which modules are relevant to the user's question
25
+ 4. Read the relevant `system/{module}.yaml` and `system/{module}.md` files
26
+ 5. If the question involves cross-module interactions, also read C4 diagrams (`system/c4-context.mmd`, `system/c4-container.mmd`)
27
+
28
+ Do NOT ask the user which files to read. Determine this from the question context.
29
+
30
+ ---
31
+
32
+ ## Decision Logic
33
+
34
+ For every user question, follow this decision tree:
35
+
36
+ ### Path A — Answer Already Exists
37
+
38
+ If the answer is explicitly covered in the design files:
39
+ - Quote the exact file and section where the answer is found
40
+ - Provide a concise, direct answer
41
+ - Reference relevant invariants, state machines, or use cases by ID/name
42
+
43
+ **Example:** _"How is a product activated?"_ → Read `system/products.md`, find the State Machine section and the `ActivateProduct` use case. Quote them directly.
44
+
45
+ ### Path B — Design Adjustment Needed
46
+
47
+ If the answer requires modifying the current design:
48
+ 1. Explain what is missing or needs to change and why
49
+ 2. List ALL files that need modification (see Propagation Rules below)
50
+ 3. Show the proposed changes clearly
51
+ 4. Ask for confirmation before applying destructive changes (removing modules, removing endpoints, removing events)
52
+ 5. Apply the changes to all affected files after confirmation
53
+
54
+ For **additive changes** (adding fields, endpoints, use cases), apply directly without asking — these are safe and reversible.
55
+
56
+ ### Path C — Design Gap Detected
57
+
58
+ If the question reveals a gap (something the design should address but doesn't):
59
+ 1. Explain the gap and its implications
60
+ 2. Propose a solution consistent with the existing architecture
61
+ 3. List all files that would be affected
62
+ 4. Apply the changes after user confirmation
63
+
64
+ ---
65
+
66
+ ## Propagation Rules — MANDATORY
67
+
68
+ When any design file changes, you MUST propagate to all dependent files. Never modify just one file in isolation.
69
+
70
+ ### Change in `system/system.yaml`
71
+
72
+ | What changed | Propagate to |
73
+ |---|---|
74
+ | New/modified endpoint in `exposes:` | `system/{module}.yaml` → `endpoints:` section; `system/{module}.md` → Use Cases + Exposed Endpoints + Interaction Diagram |
75
+ | New/modified async event | `system/{producer}.yaml` → `events:`; `system/{consumer}.yaml` → `listeners:`; `system/{producer}.md` → Emitted Events; `system/{consumer}.md` → Use Cases + Interaction Diagram; `system/system.md` → affected module sections |
76
+ | New/modified sync call | `system/{caller}.yaml` → `ports:`; `system/{caller}.md` → Ports section; `system/{callee}.md` → note about being called |
77
+ | New module added | `system/{module}.yaml` (new); `system/{module}.md` (new); `system/system.md` → new `##` section; `system/c4-container.mmd` → new Container node + relationships |
78
+ | Module removed | All of the above in reverse — **requires user confirmation** |
79
+
80
+ ### Change in `system/{module}.yaml`
81
+
82
+ | What changed | Propagate to |
83
+ |---|---|
84
+ | New/modified entity field | `system/{module}.md` → Use Cases (request body, response fields) |
85
+ | New/modified enum with transitions | `system/{module}.md` → State Machine diagram + transition use cases |
86
+ | New/modified event with triggers | `system/{module}.md` → Emitted Events; `system/system.yaml` → `integrations.async:` if new event |
87
+ | New/modified listener | `system/{module}.md` → Use Cases (incoming event handlers) |
88
+ | New/modified value object | `system/{module}.md` → Module Role or relevant use cases |
89
+
90
+ ### Change in `system/{module}.md`
91
+
92
+ Narrative-only changes (clarifications, better descriptions) do NOT propagate — they are documentation improvements.
93
+
94
+ ### Change affecting C4 diagrams
95
+
96
+ Update `system/c4-container.mmd` when:
97
+ - A module is added or removed
98
+ - A new async event flow is created (new `Rel()` through the broker)
99
+ - A new sync call is created (new direct `Rel()` between containers)
100
+ - An external system is added or removed
101
+
102
+ Update `system/c4-context.mmd` when:
103
+ - A new external system is added or removed
104
+ - A new actor type is introduced
105
+
106
+ ---
107
+
108
+ ## Format and Convention Rules
109
+
110
+ When modifying design files, always follow these conventions. Read the reference specifications if you need exact structure details:
111
+
112
+ - `.agents/skills/build-system-yaml/references/system-yaml-spec.md` — for `system.yaml` structure
113
+ - `.agents/skills/build-system-yaml/references/domain-yaml-spec.md` — for `{module}.yaml` structure
114
+ - `.agents/skills/build-system-yaml/references/module-spec.md` — for `{module}.md` and `system.md` structure
115
+
116
+ ### Naming Conventions
117
+
118
+ | Element | Convention | Example |
119
+ |---|---|---|
120
+ | Modules | plural, kebab-case | `orders`, `product-catalog` |
121
+ | Events | PascalCase + past tense + `Event` suffix | `OrderPlacedEvent` |
122
+ | Topics | SCREAMING_SNAKE_CASE without prefix | `ORDER_PLACED` |
123
+ | Ports | PascalCase + `Service` suffix, unique per module | `OrderCustomerService` |
124
+ | Use Cases | PascalCase, Verb + Noun | `CreateOrder`, `ConfirmOrder` |
125
+ | Entities in YAML | camelCase | `orderItem` |
126
+ | Aggregates | PascalCase | `Order` |
127
+ | Table names | snake_case | `order_items` |
128
+
129
+ ### Structural Rules
130
+
131
+ - No circular sync dependencies (if A calls B, B cannot call A)
132
+ - No domain fields in `system.yaml` — those belong in `{module}.yaml`
133
+ - Port service names must be unique per module (`OrderCustomerService`, not `CustomerService`)
134
+ - `endpoints:` in domain YAML uses `{ basePath, versions: [{ version, operations }] }` — NEVER a flat list
135
+ - Events declared in `{module}.yaml` must match `integrations.async[]` in `system.yaml`
136
+ - Listeners declared in `{module}.yaml` must match `consumers[]` entries in `system.yaml`
137
+ - Ports declared in `{module}.yaml` must match `integrations.sync[]` in `system.yaml`
138
+ - Audit fields (`createdAt`, `updatedAt`, `createdBy`, `updatedBy`) are NEVER in `fields:` — use `audit.enabled: true`
139
+ - Enum transitions require `initialValue`
140
+ - `hasSoftDelete: true` only on root entities (`isRoot: true`)
141
+ - Cross-aggregate references use `reference:` on ID fields, never `relationships:`
142
+
143
+ ### Language Rule
144
+
145
+ **ALL content in `.yaml`, `.md`, and `.mmd` files MUST be in English.** The conversation with the user can be in any language; the files are always in English.
146
+
147
+ ---
148
+
149
+ ## What This Agent Does NOT Do
150
+
151
+ - **Does not generate a design from scratch** — use the `build-system-yaml` skill for that
152
+ - **Does not generate Java code** — use `eva g entities`, `eva g resource`, etc.
153
+ - **Does not run CLI commands** — it only reads and modifies design files in `system/`
154
+ - **Does not modify files outside `system/`** — AGENTS.md, src/, templates/ are out of scope
155
+
156
+ ---
157
+
158
+ ## Response Style
159
+
160
+ - **Consultive questions**: Answer directly. Cite the file and section. Be concise.
161
+ - **Design changes**: Explain the change, list affected files, apply changes. Summarize what was modified.
162
+ - **Ambiguous questions**: Ask for clarification — but never more than 2–3 questions at a time.
163
+ - **Language**: Match the user's language in conversation. Files always in English.