@pattern-stack/codegen 0.2.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 (279) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +214 -0
  3. package/dist/runtime/analytics/index.d.ts +6 -0
  4. package/dist/runtime/analytics/index.js +49 -0
  5. package/dist/runtime/analytics/index.js.map +1 -0
  6. package/dist/runtime/analytics/metrics.d.ts +75 -0
  7. package/dist/runtime/analytics/metrics.js +1 -0
  8. package/dist/runtime/analytics/metrics.js.map +1 -0
  9. package/dist/runtime/analytics/packs/crm-entity-measures.d.ts +21 -0
  10. package/dist/runtime/analytics/packs/crm-entity-measures.js +1 -0
  11. package/dist/runtime/analytics/packs/crm-entity-measures.js.map +1 -0
  12. package/dist/runtime/analytics/packs/index.d.ts +3 -0
  13. package/dist/runtime/analytics/packs/index.js +1 -0
  14. package/dist/runtime/analytics/packs/index.js.map +1 -0
  15. package/dist/runtime/analytics/packs/monetary-measures.d.ts +21 -0
  16. package/dist/runtime/analytics/packs/monetary-measures.js +1 -0
  17. package/dist/runtime/analytics/packs/monetary-measures.js.map +1 -0
  18. package/dist/runtime/analytics/specs.d.ts +49 -0
  19. package/dist/runtime/analytics/specs.js +1 -0
  20. package/dist/runtime/analytics/specs.js.map +1 -0
  21. package/dist/runtime/analytics/types.d.ts +85 -0
  22. package/dist/runtime/analytics/types.js +49 -0
  23. package/dist/runtime/analytics/types.js.map +1 -0
  24. package/dist/runtime/base-classes/activity-entity-repository.d.ts +26 -0
  25. package/dist/runtime/base-classes/activity-entity-repository.js +195 -0
  26. package/dist/runtime/base-classes/activity-entity-repository.js.map +1 -0
  27. package/dist/runtime/base-classes/activity-entity-service.d.ts +39 -0
  28. package/dist/runtime/base-classes/activity-entity-service.js +214 -0
  29. package/dist/runtime/base-classes/activity-entity-service.js.map +1 -0
  30. package/dist/runtime/base-classes/base-read-use-cases.d.ts +68 -0
  31. package/dist/runtime/base-classes/base-read-use-cases.js +32 -0
  32. package/dist/runtime/base-classes/base-read-use-cases.js.map +1 -0
  33. package/dist/runtime/base-classes/base-repository.d.ts +99 -0
  34. package/dist/runtime/base-classes/base-repository.js +160 -0
  35. package/dist/runtime/base-classes/base-repository.js.map +1 -0
  36. package/dist/runtime/base-classes/base-service.d.ts +98 -0
  37. package/dist/runtime/base-classes/base-service.js +186 -0
  38. package/dist/runtime/base-classes/base-service.js.map +1 -0
  39. package/dist/runtime/base-classes/index.d.ts +18 -0
  40. package/dist/runtime/base-classes/index.js +617 -0
  41. package/dist/runtime/base-classes/index.js.map +1 -0
  42. package/dist/runtime/base-classes/knowledge-entity-repository.d.ts +17 -0
  43. package/dist/runtime/base-classes/knowledge-entity-repository.js +166 -0
  44. package/dist/runtime/base-classes/knowledge-entity-repository.js.map +1 -0
  45. package/dist/runtime/base-classes/knowledge-entity-service.d.ts +15 -0
  46. package/dist/runtime/base-classes/knowledge-entity-service.js +192 -0
  47. package/dist/runtime/base-classes/knowledge-entity-service.js.map +1 -0
  48. package/dist/runtime/base-classes/lifecycle-events.d.ts +49 -0
  49. package/dist/runtime/base-classes/lifecycle-events.js +76 -0
  50. package/dist/runtime/base-classes/lifecycle-events.js.map +1 -0
  51. package/dist/runtime/base-classes/metadata-entity-repository.d.ts +27 -0
  52. package/dist/runtime/base-classes/metadata-entity-repository.js +212 -0
  53. package/dist/runtime/base-classes/metadata-entity-repository.js.map +1 -0
  54. package/dist/runtime/base-classes/metadata-entity-service.d.ts +39 -0
  55. package/dist/runtime/base-classes/metadata-entity-service.js +214 -0
  56. package/dist/runtime/base-classes/metadata-entity-service.js.map +1 -0
  57. package/dist/runtime/base-classes/synced-entity-repository.d.ts +32 -0
  58. package/dist/runtime/base-classes/synced-entity-repository.js +203 -0
  59. package/dist/runtime/base-classes/synced-entity-repository.js.map +1 -0
  60. package/dist/runtime/base-classes/synced-entity-service.d.ts +41 -0
  61. package/dist/runtime/base-classes/synced-entity-service.js +215 -0
  62. package/dist/runtime/base-classes/synced-entity-service.js.map +1 -0
  63. package/dist/runtime/base-classes/with-analytics.d.ts +18 -0
  64. package/dist/runtime/base-classes/with-analytics.js +11 -0
  65. package/dist/runtime/base-classes/with-analytics.js.map +1 -0
  66. package/dist/runtime/constants/tokens.d.ts +29 -0
  67. package/dist/runtime/constants/tokens.js +8 -0
  68. package/dist/runtime/constants/tokens.js.map +1 -0
  69. package/dist/runtime/subsystems/analytics/analytics-query.protocol.d.ts +30 -0
  70. package/dist/runtime/subsystems/analytics/analytics-query.protocol.js +1 -0
  71. package/dist/runtime/subsystems/analytics/analytics-query.protocol.js.map +1 -0
  72. package/dist/runtime/subsystems/analytics/analytics.module.d.ts +34 -0
  73. package/dist/runtime/subsystems/analytics/analytics.module.js +117 -0
  74. package/dist/runtime/subsystems/analytics/analytics.module.js.map +1 -0
  75. package/dist/runtime/subsystems/analytics/analytics.tokens.d.ts +24 -0
  76. package/dist/runtime/subsystems/analytics/analytics.tokens.js +10 -0
  77. package/dist/runtime/subsystems/analytics/analytics.tokens.js.map +1 -0
  78. package/dist/runtime/subsystems/analytics/cube-backend.d.ts +28 -0
  79. package/dist/runtime/subsystems/analytics/cube-backend.js +71 -0
  80. package/dist/runtime/subsystems/analytics/cube-backend.js.map +1 -0
  81. package/dist/runtime/subsystems/analytics/index.d.ts +6 -0
  82. package/dist/runtime/subsystems/analytics/index.js +122 -0
  83. package/dist/runtime/subsystems/analytics/index.js.map +1 -0
  84. package/dist/runtime/subsystems/analytics/noop-backend.d.ts +7 -0
  85. package/dist/runtime/subsystems/analytics/noop-backend.js +25 -0
  86. package/dist/runtime/subsystems/analytics/noop-backend.js.map +1 -0
  87. package/dist/runtime/subsystems/cache/cache.drizzle-backend.d.ts +43 -0
  88. package/dist/runtime/subsystems/cache/cache.drizzle-backend.js +133 -0
  89. package/dist/runtime/subsystems/cache/cache.drizzle-backend.js.map +1 -0
  90. package/dist/runtime/subsystems/cache/cache.memory-backend.d.ts +21 -0
  91. package/dist/runtime/subsystems/cache/cache.memory-backend.js +100 -0
  92. package/dist/runtime/subsystems/cache/cache.memory-backend.js.map +1 -0
  93. package/dist/runtime/subsystems/cache/cache.module.d.ts +37 -0
  94. package/dist/runtime/subsystems/cache/cache.module.js +272 -0
  95. package/dist/runtime/subsystems/cache/cache.module.js.map +1 -0
  96. package/dist/runtime/subsystems/cache/cache.protocol.d.ts +42 -0
  97. package/dist/runtime/subsystems/cache/cache.protocol.js +1 -0
  98. package/dist/runtime/subsystems/cache/cache.protocol.js.map +1 -0
  99. package/dist/runtime/subsystems/cache/cache.schema.d.ts +64 -0
  100. package/dist/runtime/subsystems/cache/cache.schema.js +18 -0
  101. package/dist/runtime/subsystems/cache/cache.schema.js.map +1 -0
  102. package/dist/runtime/subsystems/cache/cache.tokens.d.ts +18 -0
  103. package/dist/runtime/subsystems/cache/cache.tokens.js +8 -0
  104. package/dist/runtime/subsystems/cache/cache.tokens.js.map +1 -0
  105. package/dist/runtime/subsystems/cache/index.d.ts +11 -0
  106. package/dist/runtime/subsystems/cache/index.js +277 -0
  107. package/dist/runtime/subsystems/cache/index.js.map +1 -0
  108. package/dist/runtime/subsystems/events/domain-events.schema.d.ts +187 -0
  109. package/dist/runtime/subsystems/events/domain-events.schema.js +32 -0
  110. package/dist/runtime/subsystems/events/domain-events.schema.js.map +1 -0
  111. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.d.ts +38 -0
  112. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +199 -0
  113. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js.map +1 -0
  114. package/dist/runtime/subsystems/events/event-bus.memory-backend.d.ts +18 -0
  115. package/dist/runtime/subsystems/events/event-bus.memory-backend.js +71 -0
  116. package/dist/runtime/subsystems/events/event-bus.memory-backend.js.map +1 -0
  117. package/dist/runtime/subsystems/events/event-bus.protocol.d.ts +52 -0
  118. package/dist/runtime/subsystems/events/event-bus.protocol.js +1 -0
  119. package/dist/runtime/subsystems/events/event-bus.protocol.js.map +1 -0
  120. package/dist/runtime/subsystems/events/event-bus.redis-backend.d.ts +95 -0
  121. package/dist/runtime/subsystems/events/event-bus.redis-backend.js +229 -0
  122. package/dist/runtime/subsystems/events/event-bus.redis-backend.js.map +1 -0
  123. package/dist/runtime/subsystems/events/events.module.d.ts +46 -0
  124. package/dist/runtime/subsystems/events/events.module.js +531 -0
  125. package/dist/runtime/subsystems/events/events.module.js.map +1 -0
  126. package/dist/runtime/subsystems/events/events.tokens.d.ts +19 -0
  127. package/dist/runtime/subsystems/events/events.tokens.js +8 -0
  128. package/dist/runtime/subsystems/events/events.tokens.js.map +1 -0
  129. package/dist/runtime/subsystems/events/index.d.ts +12 -0
  130. package/dist/runtime/subsystems/events/index.js +536 -0
  131. package/dist/runtime/subsystems/events/index.js.map +1 -0
  132. package/dist/runtime/subsystems/index.d.ts +24 -0
  133. package/dist/runtime/subsystems/index.js +1643 -0
  134. package/dist/runtime/subsystems/index.js.map +1 -0
  135. package/dist/runtime/subsystems/jobs/index.d.ts +14 -0
  136. package/dist/runtime/subsystems/jobs/index.js +680 -0
  137. package/dist/runtime/subsystems/jobs/index.js.map +1 -0
  138. package/dist/runtime/subsystems/jobs/job-queue.bullmq-backend.d.ts +54 -0
  139. package/dist/runtime/subsystems/jobs/job-queue.bullmq-backend.js +186 -0
  140. package/dist/runtime/subsystems/jobs/job-queue.bullmq-backend.js.map +1 -0
  141. package/dist/runtime/subsystems/jobs/job-queue.drizzle-backend.d.ts +38 -0
  142. package/dist/runtime/subsystems/jobs/job-queue.drizzle-backend.js +228 -0
  143. package/dist/runtime/subsystems/jobs/job-queue.drizzle-backend.js.map +1 -0
  144. package/dist/runtime/subsystems/jobs/job-queue.memory-backend.d.ts +12 -0
  145. package/dist/runtime/subsystems/jobs/job-queue.memory-backend.js +44 -0
  146. package/dist/runtime/subsystems/jobs/job-queue.memory-backend.js.map +1 -0
  147. package/dist/runtime/subsystems/jobs/job-queue.protocol.d.ts +48 -0
  148. package/dist/runtime/subsystems/jobs/job-queue.protocol.js +1 -0
  149. package/dist/runtime/subsystems/jobs/job-queue.protocol.js.map +1 -0
  150. package/dist/runtime/subsystems/jobs/job-queue.redis-backend.d.ts +46 -0
  151. package/dist/runtime/subsystems/jobs/job-queue.redis-backend.js +187 -0
  152. package/dist/runtime/subsystems/jobs/job-queue.redis-backend.js.map +1 -0
  153. package/dist/runtime/subsystems/jobs/job-queue.schema.d.ts +237 -0
  154. package/dist/runtime/subsystems/jobs/job-queue.schema.js +44 -0
  155. package/dist/runtime/subsystems/jobs/job-queue.schema.js.map +1 -0
  156. package/dist/runtime/subsystems/jobs/jobs.module.d.ts +18 -0
  157. package/dist/runtime/subsystems/jobs/jobs.module.js +676 -0
  158. package/dist/runtime/subsystems/jobs/jobs.module.js.map +1 -0
  159. package/dist/runtime/subsystems/jobs/jobs.tokens.d.ts +13 -0
  160. package/dist/runtime/subsystems/jobs/jobs.tokens.js +8 -0
  161. package/dist/runtime/subsystems/jobs/jobs.tokens.js.map +1 -0
  162. package/dist/runtime/subsystems/storage/index.d.ts +6 -0
  163. package/dist/runtime/subsystems/storage/index.js +204 -0
  164. package/dist/runtime/subsystems/storage/index.js.map +1 -0
  165. package/dist/runtime/subsystems/storage/storage.local-backend.d.ts +18 -0
  166. package/dist/runtime/subsystems/storage/storage.local-backend.js +108 -0
  167. package/dist/runtime/subsystems/storage/storage.local-backend.js.map +1 -0
  168. package/dist/runtime/subsystems/storage/storage.memory-backend.d.ts +28 -0
  169. package/dist/runtime/subsystems/storage/storage.memory-backend.js +72 -0
  170. package/dist/runtime/subsystems/storage/storage.memory-backend.js.map +1 -0
  171. package/dist/runtime/subsystems/storage/storage.module.d.ts +40 -0
  172. package/dist/runtime/subsystems/storage/storage.module.js +201 -0
  173. package/dist/runtime/subsystems/storage/storage.module.js.map +1 -0
  174. package/dist/runtime/subsystems/storage/storage.protocol.d.ts +69 -0
  175. package/dist/runtime/subsystems/storage/storage.protocol.js +1 -0
  176. package/dist/runtime/subsystems/storage/storage.protocol.js.map +1 -0
  177. package/dist/runtime/subsystems/storage/storage.tokens.d.ts +11 -0
  178. package/dist/runtime/subsystems/storage/storage.tokens.js +6 -0
  179. package/dist/runtime/subsystems/storage/storage.tokens.js.map +1 -0
  180. package/dist/runtime/subsystems/storage/storage.utils.d.ts +9 -0
  181. package/dist/runtime/subsystems/storage/storage.utils.js +18 -0
  182. package/dist/runtime/subsystems/storage/storage.utils.js.map +1 -0
  183. package/dist/runtime/types/drizzle.d.ts +17 -0
  184. package/dist/runtime/types/drizzle.js +1 -0
  185. package/dist/runtime/types/drizzle.js.map +1 -0
  186. package/dist/src/cli/index.d.ts +1 -0
  187. package/dist/src/cli/index.js +7365 -0
  188. package/dist/src/cli/index.js.map +1 -0
  189. package/dist/src/index.d.ts +2384 -0
  190. package/dist/src/index.js +2198 -0
  191. package/dist/src/index.js.map +1 -0
  192. package/package.json +114 -0
  193. package/templates/broadcast/new/backend-interface.ejs.t +47 -0
  194. package/templates/broadcast/new/bridge-listener.ejs.t +67 -0
  195. package/templates/broadcast/new/channel.ejs.t +77 -0
  196. package/templates/broadcast/new/index.ejs.t +21 -0
  197. package/templates/broadcast/new/memory-backend.ejs.t +87 -0
  198. package/templates/broadcast/new/module.ejs.t +57 -0
  199. package/templates/broadcast/new/prompt.js +268 -0
  200. package/templates/broadcast/new/websocket-backend.ejs.t +259 -0
  201. package/templates/entity/new/backend/application/commands/create.ejs.t +55 -0
  202. package/templates/entity/new/backend/application/commands/delete.ejs.t +45 -0
  203. package/templates/entity/new/backend/application/commands/grouped-index.ejs.t +149 -0
  204. package/templates/entity/new/backend/application/commands/index.ejs.t +15 -0
  205. package/templates/entity/new/backend/application/commands/update.ejs.t +58 -0
  206. package/templates/entity/new/backend/application/queries/declarative-queries.ejs.t +36 -0
  207. package/templates/entity/new/backend/application/queries/get-by-id.ejs.t +42 -0
  208. package/templates/entity/new/backend/application/queries/grouped-index.ejs.t +81 -0
  209. package/templates/entity/new/backend/application/queries/index.ejs.t +14 -0
  210. package/templates/entity/new/backend/application/queries/list.ejs.t +36 -0
  211. package/templates/entity/new/backend/application/schemas/_inject-index.ejs.t +7 -0
  212. package/templates/entity/new/backend/application/schemas/dto.ejs.t +45 -0
  213. package/templates/entity/new/backend/database/_inject-index.ejs.t +7 -0
  214. package/templates/entity/new/backend/database/electric-migration.ejs.t +21 -0
  215. package/templates/entity/new/backend/database/repository.ejs.t +450 -0
  216. package/templates/entity/new/backend/database/schema.ejs.t +248 -0
  217. package/templates/entity/new/backend/domain/_inject-index.ejs.t +12 -0
  218. package/templates/entity/new/backend/domain/entity.ejs.t +108 -0
  219. package/templates/entity/new/backend/domain/grouped-index.ejs.t +163 -0
  220. package/templates/entity/new/backend/domain/index.ejs.t +15 -0
  221. package/templates/entity/new/backend/domain/repository-interface.ejs.t +71 -0
  222. package/templates/entity/new/backend/modules/core/_ensure-anchor-tokens.ejs.t +10 -0
  223. package/templates/entity/new/backend/modules/core/_inject-token.ejs.t +7 -0
  224. package/templates/entity/new/backend/modules/core/module.ejs.t +67 -0
  225. package/templates/entity/new/backend/modules/trpc/module.ejs.t +67 -0
  226. package/templates/entity/new/backend/presentation/controller.ejs.t +201 -0
  227. package/templates/entity/new/clean-lite-ps/controller.ejs.t +37 -0
  228. package/templates/entity/new/clean-lite-ps/dto/create.ejs.t +17 -0
  229. package/templates/entity/new/clean-lite-ps/dto/output.ejs.t +25 -0
  230. package/templates/entity/new/clean-lite-ps/dto/update.ejs.t +11 -0
  231. package/templates/entity/new/clean-lite-ps/entity.ejs.t +52 -0
  232. package/templates/entity/new/clean-lite-ps/index.ejs.t +20 -0
  233. package/templates/entity/new/clean-lite-ps/module.ejs.t +43 -0
  234. package/templates/entity/new/clean-lite-ps/prompt-extension.js +617 -0
  235. package/templates/entity/new/clean-lite-ps/repository.ejs.t +62 -0
  236. package/templates/entity/new/clean-lite-ps/service.ejs.t +34 -0
  237. package/templates/entity/new/clean-lite-ps/use-cases/declarative-queries.ejs.t +34 -0
  238. package/templates/entity/new/clean-lite-ps/use-cases/find-by-id.ejs.t +16 -0
  239. package/templates/entity/new/clean-lite-ps/use-cases/list.ejs.t +16 -0
  240. package/templates/entity/new/frontend/_inject-entities-entry.ejs.t +7 -0
  241. package/templates/entity/new/frontend/_inject-entities-import.ejs.t +7 -0
  242. package/templates/entity/new/frontend/collections/_ensure-anchor-collections.ejs.t +10 -0
  243. package/templates/entity/new/frontend/collections/_inject-index.ejs.t +9 -0
  244. package/templates/entity/new/frontend/collections/_inject-schema-import.ejs.t +9 -0
  245. package/templates/entity/new/frontend/collections/collection.ejs.t +61 -0
  246. package/templates/entity/new/frontend/collections/collections-base.ejs.t +24 -0
  247. package/templates/entity/new/frontend/entity/collection.ejs.t +172 -0
  248. package/templates/entity/new/frontend/entity/combined.ejs.t +474 -0
  249. package/templates/entity/new/frontend/entity/fields.ejs.t +104 -0
  250. package/templates/entity/new/frontend/entity/hooks.ejs.t +73 -0
  251. package/templates/entity/new/frontend/entity/index.ejs.t +21 -0
  252. package/templates/entity/new/frontend/entity/mutation-hooks.ejs.t +84 -0
  253. package/templates/entity/new/frontend/entity/mutations.ejs.t +38 -0
  254. package/templates/entity/new/frontend/entity/types.ejs.t +59 -0
  255. package/templates/entity/new/frontend/generated/_inject-index-export.ejs.t +7 -0
  256. package/templates/entity/new/frontend/generated/_inject-index-import.ejs.t +7 -0
  257. package/templates/entity/new/frontend/generated/_inject-index-registry.ejs.t +7 -0
  258. package/templates/entity/new/frontend/store/_inject-collection-import.ejs.t +9 -0
  259. package/templates/entity/new/frontend/store/_inject-collections.ejs.t +9 -0
  260. package/templates/entity/new/frontend/store/_inject-entity.ejs.t +9 -0
  261. package/templates/entity/new/frontend/store/_inject-import.ejs.t +9 -0
  262. package/templates/entity/new/frontend/store/_inject-lookups.ejs.t +9 -0
  263. package/templates/entity/new/frontend/store/_inject-resolve.ejs.t +10 -0
  264. package/templates/entity/new/frontend/store/hooks.ejs.t +72 -0
  265. package/templates/entity/new/frontend/unified-entity.ejs.t +28 -0
  266. package/templates/entity/new/prompt.js +1421 -0
  267. package/templates/relationship/new/controller.ejs.t +36 -0
  268. package/templates/relationship/new/dto/create.ejs.t +41 -0
  269. package/templates/relationship/new/dto/output.ejs.t +44 -0
  270. package/templates/relationship/new/dto/update.ejs.t +10 -0
  271. package/templates/relationship/new/entity.ejs.t +98 -0
  272. package/templates/relationship/new/index.ejs.t +19 -0
  273. package/templates/relationship/new/module.ejs.t +35 -0
  274. package/templates/relationship/new/prompt.js +682 -0
  275. package/templates/relationship/new/repository.ejs.t +54 -0
  276. package/templates/relationship/new/service.ejs.t +31 -0
  277. package/templates/relationship/new/use-cases/declarative-queries.ejs.t +34 -0
  278. package/templates/relationship/new/use-cases/find-by-id.ejs.t +16 -0
  279. package/templates/relationship/new/use-cases/list.ejs.t +16 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/scanner/framework-detector.ts","../../../src/scanner/orm-detector.ts","../../../src/scanner/architecture-detector.ts","../../../src/scanner/naming-detector.ts","../../../src/scanner/types.ts","../../../src/scanner/config-generator.ts","../../../src/scanner/index.ts","../../../src/cli/shared/context.ts","../../../src/cli/ui/theme.ts","../../../src/cli/ui/json.ts","../../../src/cli/ui/pane.ts","../../../src/cli/ui/hints.ts","../../../src/cli/ui/icons.ts","../../../src/schema/entity-definition.schema.ts","../../../src/schema/relationship-definition.schema.ts","../../../src/utils/yaml-loader.ts","../../../src/parser/load-entities.ts","../../../src/parser/index.ts","../../../src/analyzer/graph-builder.ts","../../../src/behaviors/external-id-tracking.ts","../../../src/behaviors/soft-delete.ts","../../../src/behaviors/timestamps.ts","../../../src/behaviors/user-tracking.ts","../../../src/behaviors/index.ts","../../../src/analyzer/consistency-checker.ts","../../../src/analyzer/statistics.ts","../../../src/analyzer/transitive-suggester.ts","../../../src/analyzer/manifest.ts","../../../src/analyzer/serialize-graph.ts","../../../src/analyzer/types.ts","../../../src/analyzer/index.ts","../../../src/formatters/console-formatter.ts","../../../src/formatters/json-formatter.ts","../../../src/formatters/markdown-formatter.ts","../../../src/formatters/index.ts","../../../src/index.ts","../../../src/cli/shared/hygen.ts","../../../src/cli/shared/git-safety.ts","../../../src/cli/shared/barrel-generator.ts","../../../src/cli/ui/output.ts","../../../src/cli/commands/entity.ts","../../../src/cli/shared/runtime-copier.ts","../../../src/cli/shared/subsystem-detect.ts","../../../src/cli/commands/subsystem.ts","../../../src/cli/shared/init-scaffold.ts","../../../src/cli/commands/project.ts","../../../src/cli/commands/dev.ts","../../../src/cli/commands/relationship.ts","../../../src/cli/shortcuts/init.ts","../../../src/cli/index.ts","../../../src/cli/noun-module.ts"],"sourcesContent":["/**\n * Framework Detector\n *\n * Detects which framework a project uses by scanning for telltale imports and patterns.\n */\n\nimport { existsSync, readdirSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { DetectionResult } from './types.js';\n\nexport type FrameworkType = 'nestjs' | 'fastify' | 'express' | 'plain';\n\ninterface FrameworkMarkers {\n\timports: RegExp[];\n\tpatterns: RegExp[];\n\tfilePatterns: RegExp[];\n}\n\nconst FRAMEWORK_MARKERS: Record<FrameworkType, FrameworkMarkers> = {\n\tnestjs: {\n\t\timports: [\n\t\t\t/@nestjs\\/common/,\n\t\t\t/@nestjs\\/core/,\n\t\t],\n\t\tpatterns: [\n\t\t\t/@Controller\\(/,\n\t\t\t/@Injectable\\(/,\n\t\t\t/@Module\\(/,\n\t\t\t/@Get\\(/,\n\t\t\t/@Post\\(/,\n\t\t\t/@Put\\(/,\n\t\t\t/@Delete\\(/,\n\t\t],\n\t\tfilePatterns: [\n\t\t\t/\\.module\\.ts$/,\n\t\t\t/\\.controller\\.ts$/,\n\t\t],\n\t},\n\tfastify: {\n\t\timports: [\n\t\t\t/from ['\"]fastify['\"]/,\n\t\t\t/require\\(['\"]fastify['\"]\\)/,\n\t\t],\n\t\tpatterns: [\n\t\t\t/fastify\\(\\)/i,\n\t\t\t/Fastify\\(\\)/,\n\t\t\t/app\\.register\\(/,\n\t\t\t/fastify\\.register\\(/,\n\t\t],\n\t\tfilePatterns: [],\n\t},\n\texpress: {\n\t\timports: [\n\t\t\t/from ['\"]express['\"]/,\n\t\t\t/require\\(['\"]express['\"]\\)/,\n\t\t],\n\t\tpatterns: [\n\t\t\t/express\\(\\)/,\n\t\t\t/app\\.use\\(/,\n\t\t\t/app\\.get\\(/,\n\t\t\t/app\\.post\\(/,\n\t\t\t/Router\\(\\)/,\n\t\t],\n\t\tfilePatterns: [],\n\t},\n\tplain: {\n\t\timports: [],\n\t\tpatterns: [],\n\t\tfilePatterns: [],\n\t},\n};\n\n/**\n * Recursively get all TypeScript files in a directory, excluding node_modules\n */\nfunction getAllTsFiles(dir: string, files: string[] = []): string[] {\n\tif (!existsSync(dir)) return files;\n\n\ttry {\n\t\tconst entries = readdirSync(dir, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\t// Skip node_modules and hidden directories\n\t\t\tif (entry.name === 'node_modules' || entry.name.startsWith('.')) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst fullPath = join(dir, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tgetAllTsFiles(fullPath, files);\n\t\t\t} else if (entry.isFile() && entry.name.endsWith('.ts')) {\n\t\t\t\tfiles.push(fullPath);\n\t\t\t}\n\t\t}\n\t} catch (err) {\n\t\t// Silently skip directories we can't read\n\t\treturn files;\n\t}\n\n\treturn files;\n}\n\n/**\n * Count framework markers in a file\n */\nfunction countMarkersInFile(filePath: string, markers: FrameworkMarkers): number {\n\ttry {\n\t\tconst content = readFileSync(filePath, 'utf-8');\n\t\tlet count = 0;\n\n\t\t// Check imports\n\t\tfor (const importPattern of markers.imports) {\n\t\t\tif (importPattern.test(content)) {\n\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\n\t\t// Check patterns\n\t\tfor (const pattern of markers.patterns) {\n\t\t\tif (pattern.test(content)) {\n\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\n\t\t// Check file name patterns\n\t\tfor (const filePattern of markers.filePatterns) {\n\t\t\tif (filePattern.test(filePath)) {\n\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\n\t\treturn count;\n\t} catch (err) {\n\t\t// Skip files we can't read\n\t\treturn 0;\n\t}\n}\n\n/**\n * Detect which framework a project uses\n */\nexport async function detectFramework(projectPath: string): Promise<DetectionResult<FrameworkType>> {\n\tconst tsFiles = getAllTsFiles(projectPath);\n\n\tif (tsFiles.length === 0) {\n\t\treturn {\n\t\t\tdetected: 'plain',\n\t\t\tconfidence: 0,\n\t\t\tevidence: ['No TypeScript files found'],\n\t\t};\n\t}\n\n\t// Count markers for each framework\n\tconst frameworkScores: Record<FrameworkType, { count: number; files: Set<string> }> = {\n\t\tnestjs: { count: 0, files: new Set() },\n\t\tfastify: { count: 0, files: new Set() },\n\t\texpress: { count: 0, files: new Set() },\n\t\tplain: { count: 0, files: new Set() },\n\t};\n\n\t// Scan all files\n\tfor (const file of tsFiles) {\n\t\tfor (const framework of ['nestjs', 'fastify', 'express'] as const) {\n\t\t\tconst markers = FRAMEWORK_MARKERS[framework];\n\t\t\tconst count = countMarkersInFile(file, markers);\n\t\t\tif (count > 0) {\n\t\t\t\tframeworkScores[framework].count += count;\n\t\t\t\tframeworkScores[framework].files.add(file);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Find framework with highest score\n\tlet detectedFramework: FrameworkType = 'plain';\n\tlet maxScore = 0;\n\n\tfor (const framework of ['nestjs', 'fastify', 'express'] as const) {\n\t\tif (frameworkScores[framework].count > maxScore) {\n\t\t\tmaxScore = frameworkScores[framework].count;\n\t\t\tdetectedFramework = framework;\n\t\t}\n\t}\n\n\t// Build evidence array\n\tconst evidence: string[] = [];\n\tif (detectedFramework !== 'plain') {\n\t\tconst files = Array.from(frameworkScores[detectedFramework].files);\n\t\tevidence.push(...files.map(f => f.replace(projectPath, '').replace(/^\\//, '')));\n\t} else {\n\t\tevidence.push('No framework-specific patterns detected');\n\t}\n\n\t// Calculate confidence\n\t// Confidence = (marker count / total files scanned) * 100, capped at 100\n\tconst confidence = Math.min(100, Math.round((maxScore / tsFiles.length) * 100));\n\n\treturn {\n\t\tdetected: detectedFramework,\n\t\tconfidence,\n\t\tevidence,\n\t};\n}\n","import { existsSync, readdirSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { DetectionResult } from './types.js';\n\nexport type ORMType = 'drizzle' | 'prisma' | 'typeorm' | 'none';\n\ninterface ORMMarkers {\n\tdrizzle: string[];\n\tprisma: string[];\n\ttypeorm: string[];\n}\n\n/**\n * Detect which ORM a project uses by scanning for imports, schema files, and patterns.\n */\nexport async function detectORM(projectPath: string): Promise<DetectionResult<ORMType>> {\n\tconst markers: ORMMarkers = {\n\t\tdrizzle: [],\n\t\tprisma: [],\n\t\ttypeorm: [],\n\t};\n\n\t// Fast path: Check for Prisma schema file\n\tconst prismaSchemaPath = join(projectPath, 'prisma', 'schema.prisma');\n\tif (existsSync(prismaSchemaPath)) {\n\t\tmarkers.prisma.push('prisma/schema.prisma');\n\t}\n\n\t// Get all TypeScript files (skip node_modules)\n\tconst tsFiles = findTypeScriptFiles(projectPath);\n\n\t// Scan files for ORM patterns\n\tfor (const filePath of tsFiles) {\n\t\ttry {\n\t\t\tconst content = readFileSync(filePath, 'utf-8');\n\t\t\tconst relPath = filePath.replace(projectPath, '').replace(/^\\//, '');\n\n\t\t\t// Check for Drizzle patterns\n\t\t\tif (content.includes('drizzle-orm')) {\n\t\t\t\tmarkers.drizzle.push(`${relPath} (imports drizzle-orm)`);\n\t\t\t}\n\t\t\tif (/pgTable|sqliteTable|mysqlTable/.test(content)) {\n\t\t\t\tmarkers.drizzle.push(`${relPath} (table definition)`);\n\t\t\t}\n\t\t\tif (/drizzle\\(/.test(content)) {\n\t\t\t\tmarkers.drizzle.push(`${relPath} (drizzle instance)`);\n\t\t\t}\n\t\t\tif (filePath.endsWith('.schema.ts')) {\n\t\t\t\tmarkers.drizzle.push(`${relPath} (schema file)`);\n\t\t\t}\n\n\t\t\t// Check for Prisma patterns\n\t\t\tif (content.includes('@prisma/client')) {\n\t\t\t\tmarkers.prisma.push(`${relPath} (imports @prisma/client)`);\n\t\t\t}\n\t\t\tif (/new PrismaClient\\(/.test(content)) {\n\t\t\t\tmarkers.prisma.push(`${relPath} (PrismaClient instantiation)`);\n\t\t\t}\n\n\t\t\t// Check for TypeORM patterns\n\t\t\tif (content.includes('typeorm')) {\n\t\t\t\tmarkers.typeorm.push(`${relPath} (imports typeorm)`);\n\t\t\t}\n\t\t\tif (/@Entity|@Column|@PrimaryGeneratedColumn/.test(content)) {\n\t\t\t\tmarkers.typeorm.push(`${relPath} (entity decorators)`);\n\t\t\t}\n\t\t\tif (/createConnection|DataSource/.test(content)) {\n\t\t\t\tmarkers.typeorm.push(`${relPath} (connection setup)`);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\t// Skip files that can't be read\n\t\t\tcontinue;\n\t\t}\n\t}\n\n\t// Determine which ORM has the most evidence\n\tconst counts = {\n\t\tdrizzle: new Set(markers.drizzle).size,\n\t\tprisma: new Set(markers.prisma).size,\n\t\ttypeorm: new Set(markers.typeorm).size,\n\t};\n\n\t// Find the ORM with most markers\n\tconst maxCount = Math.max(counts.drizzle, counts.prisma, counts.typeorm);\n\n\tif (maxCount === 0) {\n\t\treturn {\n\t\t\tdetected: 'none',\n\t\t\tconfidence: 100,\n\t\t\tevidence: ['No ORM-specific patterns detected'],\n\t\t};\n\t}\n\n\tlet detected: ORMType;\n\tlet evidence: string[];\n\n\tif (counts.drizzle === maxCount) {\n\t\tdetected = 'drizzle';\n\t\tevidence = Array.from(new Set(markers.drizzle));\n\t} else if (counts.prisma === maxCount) {\n\t\tdetected = 'prisma';\n\t\tevidence = Array.from(new Set(markers.prisma));\n\t} else {\n\t\tdetected = 'typeorm';\n\t\tevidence = Array.from(new Set(markers.typeorm));\n\t}\n\n\t// Calculate confidence based on marker density\n\tconst totalFiles = tsFiles.length;\n\tconst markerFiles = evidence.length;\n\tconst confidence = Math.min(100, Math.round((markerFiles / Math.max(1, totalFiles * 0.1)) * 100));\n\n\treturn {\n\t\tdetected,\n\t\tconfidence,\n\t\tevidence: evidence.slice(0, 10), // Limit to 10 examples\n\t};\n}\n\n/**\n * Recursively find all TypeScript files, excluding node_modules and common ignore patterns\n */\nfunction findTypeScriptFiles(dir: string, files: string[] = []): string[] {\n\tif (!existsSync(dir)) {\n\t\treturn files;\n\t}\n\n\ttry {\n\t\tconst entries = readdirSync(dir, { withFileTypes: true });\n\n\t\tfor (const entry of entries) {\n\t\t\t// Skip common ignore patterns\n\t\t\tif (shouldSkip(entry.name)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst fullPath = join(dir, entry.name);\n\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tfindTypeScriptFiles(fullPath, files);\n\t\t\t} else if (entry.isFile() && (entry.name.endsWith('.ts') || entry.name.endsWith('.tsx'))) {\n\t\t\t\tfiles.push(fullPath);\n\t\t\t}\n\t\t}\n\t} catch (err) {\n\t\t// Skip directories we can't read\n\t\treturn files;\n\t}\n\n\treturn files;\n}\n\n/**\n * Check if a directory or file should be skipped\n */\nfunction shouldSkip(name: string): boolean {\n\tconst skipPatterns = [\n\t\t'node_modules',\n\t\t'.git',\n\t\t'dist',\n\t\t'build',\n\t\t'coverage',\n\t\t'.next',\n\t\t'.turbo',\n\t\t'.cache',\n\t\t'vendor',\n\t];\n\n\treturn skipPatterns.includes(name);\n}\n","import { readdirSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { DetectionResult } from './types.js';\n\nexport type ArchitectureType = 'clean' | 'feature' | 'mvc' | 'flat';\n\ninterface ArchitectureScore {\n\ttype: ArchitectureType;\n\tscore: number;\n\tmatchedFolders: string[];\n\texpectedFolders: string[];\n}\n\n/**\n * Detect project architecture by analyzing folder structure.\n *\n * Supports detection of:\n * - Clean Architecture (domain/application/infrastructure/presentation)\n * - Feature-based (features/* or modules/* with mixed concerns)\n * - MVC (models/views/controllers)\n * - Flat (fallback when no pattern detected)\n */\nexport async function detectArchitecture(\n\tprojectPath: string\n): Promise<DetectionResult<ArchitectureType>> {\n\tconst scores: ArchitectureScore[] = [\n\t\tdetectCleanArchitecture(projectPath),\n\t\tdetectFeatureArchitecture(projectPath),\n\t\tdetectMVCArchitecture(projectPath),\n\t];\n\n\t// Sort by score descending\n\tscores.sort((a, b) => b.score - a.score);\n\n\tconst winner = scores[0];\n\n\t// If no architecture scored above 0, return flat\n\tif (winner.score === 0) {\n\t\treturn {\n\t\t\tdetected: 'flat',\n\t\t\tconfidence: 100,\n\t\t\tevidence: ['No architectural pattern detected'],\n\t\t};\n\t}\n\n\t// Calculate confidence as percentage of expected folders found\n\tconst confidence = Math.min(\n\t\t100,\n\t\tMath.round((winner.matchedFolders.length / winner.expectedFolders.length) * 100)\n\t);\n\n\treturn {\n\t\tdetected: winner.type,\n\t\tconfidence,\n\t\tevidence: winner.matchedFolders.length > 0\n\t\t\t? winner.matchedFolders\n\t\t\t: ['No architectural pattern detected'],\n\t};\n}\n\n/**\n * Detect Clean Architecture pattern.\n * Looks for: domain/, application(s)/, infrastructure/, presentation/\n */\nfunction detectCleanArchitecture(projectPath: string): ArchitectureScore {\n\tconst expectedFolders = [\n\t\t'domain',\n\t\t'application',\n\t\t'applications',\n\t\t'infrastructure',\n\t\t'presentation',\n\t\t'use-cases',\n\t\t'commands',\n\t\t'queries',\n\t];\n\n\tconst coreFolders = ['domain', 'application', 'applications', 'infrastructure', 'presentation'];\n\tconst matchedFolders = findMatchingFolders(projectPath, expectedFolders);\n\n\t// Count matches from core folders\n\tconst coreMatches = coreFolders.filter(folder => matchedFolders.includes(folder));\n\n\t// Must have at least 2 clean architecture layers\n\t// Common patterns: domain+infrastructure, application+infrastructure, infrastructure+presentation\n\tconst hasCleanPattern = coreMatches.length >= 2;\n\n\tconst score = hasCleanPattern ? matchedFolders.length : 0;\n\n\treturn {\n\t\ttype: 'clean',\n\t\tscore,\n\t\tmatchedFolders,\n\t\texpectedFolders: ['infrastructure', 'application'], // Minimum expected\n\t};\n}\n\n/**\n * Detect Feature-based architecture.\n * Looks for: features/* or modules/* with subfolders\n */\nfunction detectFeatureArchitecture(projectPath: string): ArchitectureScore {\n\tconst featureFolders = ['features', 'modules'];\n\tconst matchedFolders: string[] = [];\n\n\tfor (const baseFolder of featureFolders) {\n\t\tconst basePath = findFolder(projectPath, baseFolder);\n\t\tif (basePath) {\n\t\t\ttry {\n\t\t\t\tconst subfolders = readdirSync(basePath, { withFileTypes: true })\n\t\t\t\t\t.filter(dirent => dirent.isDirectory())\n\t\t\t\t\t.map(dirent => `${baseFolder}/${dirent.name}`);\n\n\t\t\t\tif (subfolders.length > 0) {\n\t\t\t\t\tmatchedFolders.push(baseFolder);\n\t\t\t\t\tmatchedFolders.push(...subfolders.slice(0, 3)); // Sample first 3\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Ignore read errors\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\ttype: 'feature',\n\t\tscore: matchedFolders.length,\n\t\tmatchedFolders,\n\t\texpectedFolders: featureFolders,\n\t};\n}\n\n/**\n * Detect MVC architecture.\n * Looks for: models/, views/, controllers/\n */\nfunction detectMVCArchitecture(projectPath: string): ArchitectureScore {\n\tconst expectedFolders = [\n\t\t'models',\n\t\t'model',\n\t\t'views',\n\t\t'view',\n\t\t'controllers',\n\t\t'controller',\n\t];\n\n\tconst coreFolders = ['models', 'views', 'controllers'];\n\tconst matchedFolders = findMatchingFolders(projectPath, expectedFolders);\n\n\t// Must have at least 2 of the 3 core MVC folders\n\tconst coreMatches = coreFolders.filter(folder =>\n\t\tmatchedFolders.includes(folder) || matchedFolders.includes(folder.slice(0, -1))\n\t);\n\n\tconst score = coreMatches.length >= 2 ? matchedFolders.length : 0;\n\n\treturn {\n\t\ttype: 'mvc',\n\t\tscore,\n\t\tmatchedFolders,\n\t\texpectedFolders: coreFolders,\n\t};\n}\n\n/**\n * Find matching folders in project root or src/ directory.\n * Returns relative paths of matched folders.\n */\nfunction findMatchingFolders(\n\tprojectPath: string,\n\tfolderNames: string[]\n): string[] {\n\tconst matched: string[] = [];\n\n\tfor (const folderName of folderNames) {\n\t\tconst foundPath = findFolder(projectPath, folderName);\n\t\tif (foundPath) {\n\t\t\tmatched.push(folderName);\n\t\t}\n\t}\n\n\treturn matched;\n}\n\n/**\n * Find a folder by name in project root or src/ subdirectory.\n * Returns absolute path if found, null otherwise.\n * Handles symlinks gracefully.\n */\nfunction findFolder(projectPath: string, folderName: string): string | null {\n\tconst candidates = [\n\t\tjoin(projectPath, folderName),\n\t\tjoin(projectPath, 'src', folderName),\n\t];\n\n\tfor (const candidate of candidates) {\n\t\ttry {\n\t\t\tconst stats = statSync(candidate);\n\t\t\tif (stats.isDirectory() || stats.isSymbolicLink()) {\n\t\t\t\treturn candidate;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Folder doesn't exist, continue\n\t\t}\n\t}\n\n\treturn null;\n}\n","/**\n * Naming Convention Detector\n *\n * Detects file naming conventions and patterns by analyzing TypeScript files.\n */\n\nimport { existsSync, readdirSync, readFileSync } from 'node:fs';\nimport { basename, join } from 'node:path';\nimport type { DetectionResult } from './types.js';\n\nexport type FileCaseType = 'kebab-case' | 'camelCase' | 'PascalCase' | 'snake_case';\nexport type FileGroupingType = 'separate' | 'grouped';\n\nexport interface NamingDetectionResult {\n\tfileCase: DetectionResult<FileCaseType>;\n\tsuffixes: string[];\n\tfileGrouping: DetectionResult<FileGroupingType>;\n}\n\ninterface SuffixCount {\n\tsuffix: string;\n\tcount: number;\n}\n\n/**\n * Patterns for detecting case styles.\n * Each pattern must match the entire filename (without extension).\n */\nconst CASE_PATTERNS: Record<FileCaseType, RegExp> = {\n\t'kebab-case': /^[a-z]+(-[a-z0-9]+)*$/,\n\t'camelCase': /^[a-z]+([A-Z][a-z0-9]*)*$/,\n\t'PascalCase': /^[A-Z][a-z0-9]*([A-Z][a-z0-9]*)*$/,\n\t'snake_case': /^[a-z]+(_[a-z0-9]+)*$/,\n};\n\n/**\n * Common file suffixes to detect\n */\nconst COMMON_SUFFIXES = [\n\t'.entity',\n\t'.service',\n\t'.controller',\n\t'.repository',\n\t'.module',\n\t'.dto',\n\t'.use-case',\n\t'.query',\n\t'.command',\n\t'.interface',\n\t'.types',\n\t'.schema',\n\t'.model',\n\t'.config',\n\t'.constants',\n\t'.utils',\n\t'.helpers',\n];\n\n/**\n * Recursively get all TypeScript files in a directory, excluding unwanted paths\n */\nfunction getAllTsFiles(dir: string, files: string[] = []): string[] {\n\tif (!existsSync(dir)) return files;\n\n\ttry {\n\t\tconst entries = readdirSync(dir, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\t// Skip excluded directories\n\t\t\tif (\n\t\t\t\tentry.name === 'node_modules' ||\n\t\t\t\tentry.name === 'dist' ||\n\t\t\t\tentry.name === 'build' ||\n\t\t\t\tentry.name === 'coverage' ||\n\t\t\t\tentry.name.startsWith('.')\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst fullPath = join(dir, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tgetAllTsFiles(fullPath, files);\n\t\t\t} else if (entry.isFile() && entry.name.endsWith('.ts')) {\n\t\t\t\t// Exclude test and type definition files\n\t\t\t\tif (\n\t\t\t\t\t!entry.name.endsWith('.test.ts') &&\n\t\t\t\t\t!entry.name.endsWith('.spec.ts') &&\n\t\t\t\t\t!entry.name.endsWith('.d.ts')\n\t\t\t\t) {\n\t\t\t\t\tfiles.push(fullPath);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch (err) {\n\t\t// Silently skip directories we can't read\n\t\treturn files;\n\t}\n\n\treturn files;\n}\n\n/**\n * Extract the base name without extension and without suffix\n */\nfunction extractBaseName(filename: string): string {\n\t// Remove .ts extension\n\tlet name = filename.replace(/\\.ts$/, '');\n\n\t// Try to remove known suffixes\n\tfor (const suffix of COMMON_SUFFIXES) {\n\t\tif (name.endsWith(suffix)) {\n\t\t\tname = name.slice(0, -suffix.length);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn name;\n}\n\n/**\n * Detect which case style a filename uses\n */\nfunction detectFileCase(filename: string): FileCaseType | null {\n\tconst baseName = extractBaseName(filename);\n\n\t// Skip index files as they don't contribute to case detection\n\tif (baseName === 'index') {\n\t\treturn null;\n\t}\n\n\tfor (const [caseType, pattern] of Object.entries(CASE_PATTERNS)) {\n\t\tif (pattern.test(baseName)) {\n\t\t\treturn caseType as FileCaseType;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Extract suffix from filename (e.g., \".entity\" from \"user.entity.ts\")\n */\nfunction extractSuffix(filename: string): string | null {\n\t// Remove .ts extension\n\tconst withoutExt = filename.replace(/\\.ts$/, '');\n\n\t// Check for known suffixes\n\tfor (const suffix of COMMON_SUFFIXES) {\n\t\tif (withoutExt.endsWith(suffix)) {\n\t\t\treturn suffix;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Check if a file is a barrel export (index.ts with multiple exports)\n */\nfunction isBarrelExport(filePath: string): boolean {\n\tif (basename(filePath) !== 'index.ts') {\n\t\treturn false;\n\t}\n\n\ttry {\n\t\tconst content = readFileSync(filePath, 'utf-8');\n\n\t\t// Count export statements\n\t\tconst exportMatches = content.match(/^export\\s+(.*from|{|class|interface|type|const|function)/gm);\n\n\t\t// A barrel export typically has multiple export statements\n\t\treturn (exportMatches?.length || 0) >= 2;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Detect file naming conventions in a project\n */\nexport async function detectNaming(projectPath: string): Promise<NamingDetectionResult> {\n\tconst tsFiles = getAllTsFiles(projectPath);\n\n\tif (tsFiles.length === 0) {\n\t\treturn {\n\t\t\tfileCase: {\n\t\t\t\tdetected: 'kebab-case',\n\t\t\t\tconfidence: 0,\n\t\t\t\tevidence: ['No TypeScript files found'],\n\t\t\t},\n\t\t\tsuffixes: [],\n\t\t\tfileGrouping: {\n\t\t\t\tdetected: 'separate',\n\t\t\t\tconfidence: 0,\n\t\t\t\tevidence: ['No TypeScript files found'],\n\t\t\t},\n\t\t};\n\t}\n\n\t// Count case styles\n\tconst caseCounts: Record<FileCaseType, number> = {\n\t\t'kebab-case': 0,\n\t\t'camelCase': 0,\n\t\t'PascalCase': 0,\n\t\t'snake_case': 0,\n\t};\n\n\tconst caseEvidence: Record<FileCaseType, Set<string>> = {\n\t\t'kebab-case': new Set(),\n\t\t'camelCase': new Set(),\n\t\t'PascalCase': new Set(),\n\t\t'snake_case': new Set(),\n\t};\n\n\t// Count suffixes\n\tconst suffixCounts = new Map<string, number>();\n\n\t// Count barrel exports vs separate files\n\tlet barrelExports = 0;\n\tlet separateFiles = 0;\n\tconst barrelFiles: string[] = [];\n\tconst separateFileExamples: string[] = [];\n\n\t// Analyze each file\n\tfor (const file of tsFiles) {\n\t\tconst filename = basename(file);\n\n\t\t// Detect case style\n\t\tconst caseType = detectFileCase(filename);\n\t\tif (caseType) {\n\t\t\tcaseCounts[caseType]++;\n\t\t\tcaseEvidence[caseType].add(file.replace(projectPath, '').replace(/^\\//, ''));\n\t\t}\n\n\t\t// Detect suffix\n\t\tconst suffix = extractSuffix(filename);\n\t\tif (suffix) {\n\t\t\tsuffixCounts.set(suffix, (suffixCounts.get(suffix) || 0) + 1);\n\t\t\tseparateFiles++;\n\t\t\tif (separateFileExamples.length < 3) {\n\t\t\t\tseparateFileExamples.push(file.replace(projectPath, '').replace(/^\\//, ''));\n\t\t\t}\n\t\t}\n\n\t\t// Detect barrel exports\n\t\tif (isBarrelExport(file)) {\n\t\t\tbarrelExports++;\n\t\t\tbarrelFiles.push(file.replace(projectPath, '').replace(/^\\//, ''));\n\t\t}\n\t}\n\n\t// Determine dominant case style\n\tlet detectedCase: FileCaseType = 'kebab-case';\n\tlet maxCaseCount = 0;\n\n\tfor (const [caseType, count] of Object.entries(caseCounts)) {\n\t\tif (count > maxCaseCount) {\n\t\t\tmaxCaseCount = count;\n\t\t\tdetectedCase = caseType as FileCaseType;\n\t\t}\n\t}\n\n\t// Calculate case confidence\n\tconst analyzedFiles = Object.values(caseCounts).reduce((sum, count) => sum + count, 0);\n\tconst caseConfidence = analyzedFiles > 0\n\t\t? Math.round((maxCaseCount / analyzedFiles) * 100)\n\t\t: 0;\n\n\t// Get evidence for detected case\n\tconst caseEvidenceArray = Array.from(caseEvidence[detectedCase]).slice(0, 5);\n\n\t// Sort suffixes by count and extract top ones\n\tconst sortedSuffixes: SuffixCount[] = Array.from(suffixCounts.entries())\n\t\t.map(([suffix, count]) => ({ suffix, count }))\n\t\t.sort((a, b) => b.count - a.count);\n\n\tconst detectedSuffixes = sortedSuffixes.map(s => s.suffix);\n\n\t// Determine file grouping style\n\tconst totalFiles = tsFiles.length;\n\tconst groupingRatio = barrelExports / totalFiles;\n\tconst separateRatio = separateFiles / totalFiles;\n\n\tlet detectedGrouping: FileGroupingType;\n\tlet groupingConfidence: number;\n\tlet groupingEvidence: string[];\n\n\tif (barrelExports === 0 && separateFiles === 0) {\n\t\t// No clear pattern\n\t\tdetectedGrouping = 'separate';\n\t\tgroupingConfidence = 50;\n\t\tgroupingEvidence = ['No clear grouping pattern detected'];\n\t} else if (groupingRatio > separateRatio) {\n\t\t// More barrel exports than separate files\n\t\tdetectedGrouping = 'grouped';\n\t\tgroupingConfidence = Math.min(100, Math.round(groupingRatio * 100));\n\t\tgroupingEvidence = barrelFiles.slice(0, 5);\n\t} else {\n\t\t// More separate files\n\t\tdetectedGrouping = 'separate';\n\t\tgroupingConfidence = Math.min(100, Math.round(separateRatio * 100));\n\t\tgroupingEvidence = separateFileExamples;\n\t}\n\n\treturn {\n\t\tfileCase: {\n\t\t\tdetected: detectedCase,\n\t\t\tconfidence: caseConfidence,\n\t\t\tevidence: caseEvidenceArray.length > 0\n\t\t\t\t? caseEvidenceArray\n\t\t\t\t: ['No clear case pattern detected'],\n\t\t},\n\t\tsuffixes: detectedSuffixes,\n\t\tfileGrouping: {\n\t\t\tdetected: detectedGrouping,\n\t\t\tconfidence: groupingConfidence,\n\t\t\tevidence: groupingEvidence,\n\t\t},\n\t};\n}\n","export interface DetectionResult<T> {\n\tdetected: T;\n\tconfidence: number; // 0-100\n\tevidence: string[]; // Files/patterns that led to detection\n}\n\nexport interface ProjectProfile {\n\tframework: DetectionResult<'nestjs' | 'fastify' | 'express' | 'plain'>;\n\torm: DetectionResult<'drizzle' | 'prisma' | 'typeorm' | 'none'>;\n\tarchitecture: DetectionResult<'clean' | 'feature' | 'mvc' | 'flat'>;\n\tnaming: {\n\t\tfileCase: DetectionResult<'kebab-case' | 'camelCase' | 'PascalCase' | 'snake_case'>;\n\t\tsuffixes: string[]; // detected suffixes like .entity.ts, .service.ts\n\t\tfileGrouping: DetectionResult<'separate' | 'grouped'>;\n\t};\n\tpaths: {\n\t\troot: string;\n\t\tsrc: string | null;\n\t};\n}\n\nexport interface ScanOptions {\n\tdirectory: string;\n\tverbose?: boolean;\n}\n","import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport type { ProjectProfile } from './types.js';\n\nexport interface ProposedConfig {\n\t// Core settings\n\tframework: 'nestjs' | 'fastify' | 'express' | 'plain';\n\torm: 'drizzle' | 'prisma' | 'typeorm' | 'none';\n\n\t// Layout settings (matching existing codegen.config.yaml schema)\n\tfolder_structure: 'nested' | 'flat';\n\tfile_grouping: 'separate' | 'grouped';\n\n\t// Naming conventions (extended to match naming-config.schema.ts)\n\tnaming: {\n\t\tfileCase: 'kebab-case' | 'camelCase' | 'PascalCase' | 'snake_case';\n\t\tsuffixes: string[];\n\t\t// Derived from suffixes analysis\n\t\tsuffixStyle?: 'dotted' | 'suffixed' | 'worded';\n\t\tentityInclusion?: 'always' | 'never' | 'flat-only';\n\t\tterminology?: {\n\t\t\tcommand?: 'command' | 'use-case';\n\t\t\tquery?: 'query' | 'use-case';\n\t\t};\n\t};\n\n\t// Paths (inferred from architecture)\n\tpaths: {\n\t\tbackend_src: string;\n\t\tdomain: string;\n\t\tapplication: string;\n\t\tinfrastructure: string;\n\t\tpresentation: string;\n\t\tfrontend_src?: string;\n\t};\n\n\t// Generation toggles emitted into the `generate` block of codegen.config.yaml.\n\t// Matches GenerateConfigSchema.\n\tgenerate: {\n\t\t/** Which backend architecture to emit. Defaults to 'clean'. */\n\t\tarchitecture: 'clean' | 'clean-lite-ps';\n\t\t/** Whether to emit the frontend pipeline at all. Default is false unless\n\t\t * detection found an `apps/frontend/` directory or the profile set an\n\t\t * explicit `paths.frontend_src`. */\n\t\tfrontend: boolean;\n\t};\n\n\t// Confidence summary\n\tconfidence: {\n\t\toverall: number;\n\t\tframework: number;\n\t\torm: number;\n\t\tarchitecture: number;\n\t\tnaming: number;\n\t};\n}\n\n/**\n * Generate a proposed codegen configuration from detected project profile.\n *\n * Takes detector results and produces a configuration matching the\n * codegen.config.yaml schema with confidence scores for transparency.\n *\n * @param profile - Detected project characteristics from scanProject\n * @returns Proposed configuration with confidence metrics\n */\nexport function generateConfig(profile: ProjectProfile): ProposedConfig {\n\t// 1. Framework & ORM: Direct passthrough from detection\n\tconst framework = profile.framework.detected;\n\tconst orm = profile.orm.detected;\n\n\t// 2. Folder Structure: Based on architecture\n\tconst folder_structure = inferFolderStructure(profile.architecture.detected);\n\n\t// 3. File Grouping: Direct from naming detection\n\tconst file_grouping = profile.naming.fileGrouping.detected;\n\n\t// 4. Paths: Map from architecture detection\n\tconst paths = inferPaths(profile);\n\n\t// 5. Naming conventions (with derived fields)\n\tconst naming = buildNamingConfig(profile);\n\n\t// 6. Generate toggles — architecture is always 'clean' by default (the\n\t// auto-detected path for new projects); frontend is true iff either the\n\t// profile exposed an explicit frontend_src or an `apps/frontend/`\n\t// directory exists under the project root.\n\tconst generate = buildGenerateConfig(profile, paths);\n\n\t// 7. Confidence: Calculate overall confidence\n\tconst confidence = calculateConfidence(profile);\n\n\treturn {\n\t\tframework,\n\t\torm,\n\t\tfolder_structure,\n\t\tfile_grouping,\n\t\tnaming,\n\t\tpaths,\n\t\tgenerate,\n\t\tconfidence,\n\t};\n}\n\n/**\n * Build the `generate` block for the proposed config.\n *\n * Detection rules for `frontend`:\n * - true if `profile.paths` or `paths.frontend_src` is explicitly set (non-empty string)\n * - true if `apps/frontend/` exists under the project root\n * - false otherwise (backend-only default)\n */\nfunction buildGenerateConfig(\n\tprofile: ProjectProfile,\n\tpaths: ProposedConfig['paths']\n): ProposedConfig['generate'] {\n\tconst explicitFrontendSrc =\n\t\ttypeof paths.frontend_src === 'string' && paths.frontend_src.length > 0;\n\tconst appsFrontendExists = existsSync(join(profile.paths.root, 'apps', 'frontend'));\n\n\treturn {\n\t\tarchitecture: 'clean',\n\t\tfrontend: explicitFrontendSrc || appsFrontendExists,\n\t};\n}\n\n/**\n * Build naming configuration from detected patterns.\n *\n * Derives additional fields from the base detection:\n * - suffixStyle: inferred from suffix patterns (dotted, suffixed, worded)\n * - terminology: inferred from command/use-case patterns\n * - entityInclusion: defaults to flat-only (most common)\n */\nfunction buildNamingConfig(profile: ProjectProfile): ProposedConfig['naming'] {\n\tconst fileCase = profile.naming.fileCase.detected;\n\tconst suffixes = profile.naming.suffixes;\n\n\tconst result: ProposedConfig['naming'] = {\n\t\tfileCase,\n\t\tsuffixes,\n\t};\n\n\t// Derive suffixStyle from suffix patterns\n\tconst suffixStyle = deriveSuffixStyle(suffixes);\n\tif (suffixStyle) {\n\t\tresult.suffixStyle = suffixStyle;\n\t}\n\n\t// Derive terminology from suffix patterns\n\tconst terminology = deriveTerminology(suffixes);\n\tif (terminology) {\n\t\tresult.terminology = terminology;\n\t}\n\n\t// Default entityInclusion to flat-only (most common pattern)\n\tresult.entityInclusion = 'flat-only';\n\n\treturn result;\n}\n\n/**\n * Derive suffix style from detected suffixes.\n *\n * Analyzes suffix patterns to determine:\n * - dotted: .entity.ts, .service.ts (starts with .)\n * - suffixed: Entity.ts, Service.ts (PascalCase suffix)\n * - worded: -entity.ts, -service.ts (hyphenated)\n *\n * Minimum confidence: 50% of suffixes must match a pattern.\n */\nfunction deriveSuffixStyle(suffixes: string[]): 'dotted' | 'suffixed' | 'worded' | undefined {\n\tif (suffixes.length === 0) return undefined;\n\n\tlet dottedCount = 0;\n\tlet wordedCount = 0;\n\tlet suffixedCount = 0;\n\n\tfor (const suffix of suffixes) {\n\t\tif (suffix.startsWith('.')) {\n\t\t\tdottedCount++;\n\t\t} else if (suffix.startsWith('-')) {\n\t\t\twordedCount++;\n\t\t} else if (/^[A-Z]/.test(suffix)) {\n\t\t\tsuffixedCount++;\n\t\t}\n\t}\n\n\tconst total = suffixes.length;\n\tconst threshold = total * 0.5;\n\n\tif (dottedCount >= threshold) return 'dotted';\n\tif (wordedCount >= threshold) return 'worded';\n\tif (suffixedCount >= threshold) return 'suffixed';\n\n\treturn undefined;\n}\n\n/**\n * Derive terminology from detected suffixes.\n *\n * Checks for use-case vs command/query patterns:\n * - .use-case.ts → { command: 'use-case', query: 'use-case' }\n * - .command.ts → { command: 'command' }\n * - .query.ts → { query: 'query' }\n */\nfunction deriveTerminology(\n\tsuffixes: string[]\n): { command?: 'command' | 'use-case'; query?: 'query' | 'use-case' } | undefined {\n\tconst hasUseCase = suffixes.some(\n\t\t(s) => s.includes('use-case') || s.includes('usecase') || s.includes('UseCase')\n\t);\n\tconst hasCommand = suffixes.some((s) => s.includes('command') || s.includes('Command'));\n\tconst hasQuery = suffixes.some((s) => s.includes('query') || s.includes('Query'));\n\n\tif (!hasUseCase && !hasCommand && !hasQuery) {\n\t\treturn undefined;\n\t}\n\n\tconst result: { command?: 'command' | 'use-case'; query?: 'query' | 'use-case' } = {};\n\n\tif (hasUseCase) {\n\t\tresult.command = 'use-case';\n\t\tresult.query = 'use-case';\n\t} else {\n\t\tif (hasCommand) result.command = 'command';\n\t\tif (hasQuery) result.query = 'query';\n\t}\n\n\treturn Object.keys(result).length > 0 ? result : undefined;\n}\n\n/**\n * Infer folder structure preference from architecture type.\n *\n * Clean and feature architectures benefit from nested structures.\n * MVC and flat architectures typically use flat layouts.\n */\nfunction inferFolderStructure(architecture: 'clean' | 'feature' | 'mvc' | 'flat'): 'nested' | 'flat' {\n\tswitch (architecture) {\n\t\tcase 'clean':\n\t\tcase 'feature':\n\t\t\treturn 'nested';\n\t\tcase 'mvc':\n\t\tcase 'flat':\n\t\tdefault:\n\t\t\treturn 'flat';\n\t}\n}\n\n/**\n * Infer project paths from architecture detection and project structure.\n *\n * Maps architecture patterns to expected directory structure:\n * - Clean: domain/, application/, infrastructure/, presentation/\n * - Feature: features/ or modules/\n * - MVC: models/, controllers/, services/\n * - Flat: src/ (fallback)\n */\nfunction inferPaths(profile: ProjectProfile): ProposedConfig['paths'] {\n\tconst root = profile.paths.root;\n\tconst srcBase = profile.paths.src || root;\n\tconst architecture = profile.architecture.detected;\n\n\t// Default paths structure\n\tconst defaultPaths = {\n\t\tbackend_src: srcBase,\n\t\tdomain: `${srcBase}/domain`,\n\t\tapplication: `${srcBase}/application`,\n\t\tinfrastructure: `${srcBase}/infrastructure`,\n\t\tpresentation: `${srcBase}/presentation`,\n\t};\n\n\t// Architecture-specific path overrides\n\tswitch (architecture) {\n\t\tcase 'clean': {\n\t\t\t// Clean architecture: Check evidence for actual folder names\n\t\t\tconst evidence = profile.architecture.evidence;\n\t\t\treturn {\n\t\t\t\tbackend_src: srcBase,\n\t\t\t\tdomain: findPathInEvidence(evidence, ['domain'], srcBase),\n\t\t\t\tapplication: findPathInEvidence(\n\t\t\t\t\tevidence,\n\t\t\t\t\t['application', 'applications', 'use-cases'],\n\t\t\t\t\tsrcBase\n\t\t\t\t),\n\t\t\t\tinfrastructure: findPathInEvidence(evidence, ['infrastructure'], srcBase),\n\t\t\t\tpresentation: findPathInEvidence(evidence, ['presentation', 'controllers'], srcBase),\n\t\t\t};\n\t\t}\n\n\t\tcase 'feature': {\n\t\t\t// Feature-based: Use features/ or modules/ as base\n\t\t\tconst evidence = profile.architecture.evidence;\n\t\t\tconst featureBase = findPathInEvidence(evidence, ['features', 'modules'], srcBase);\n\t\t\treturn {\n\t\t\t\tbackend_src: srcBase,\n\t\t\t\tdomain: `${featureBase}/{feature}/domain`,\n\t\t\t\tapplication: `${featureBase}/{feature}/application`,\n\t\t\t\tinfrastructure: `${featureBase}/{feature}/infrastructure`,\n\t\t\t\tpresentation: `${featureBase}/{feature}/presentation`,\n\t\t\t};\n\t\t}\n\n\t\tcase 'mvc': {\n\t\t\t// MVC architecture\n\t\t\treturn {\n\t\t\t\tbackend_src: srcBase,\n\t\t\t\tdomain: `${srcBase}/models`,\n\t\t\t\tapplication: `${srcBase}/services`,\n\t\t\t\tinfrastructure: `${srcBase}/lib`,\n\t\t\t\tpresentation: `${srcBase}/controllers`,\n\t\t\t};\n\t\t}\n\n\t\tcase 'flat':\n\t\tdefault: {\n\t\t\t// Flat structure: Everything in src/\n\t\t\treturn {\n\t\t\t\tbackend_src: srcBase,\n\t\t\t\tdomain: srcBase,\n\t\t\t\tapplication: srcBase,\n\t\t\t\tinfrastructure: srcBase,\n\t\t\t\tpresentation: srcBase,\n\t\t\t};\n\t\t}\n\t}\n}\n\n/**\n * Find the actual path from evidence, falling back to default.\n *\n * Evidence contains folder names found during detection.\n * We look for matches in the candidates list and construct full path.\n */\nfunction findPathInEvidence(\n\tevidence: string[],\n\tcandidates: string[],\n\tsrcBase: string\n): string {\n\tfor (const candidate of candidates) {\n\t\t// Look for exact match in evidence\n\t\tif (evidence.includes(candidate)) {\n\t\t\treturn `${srcBase}/${candidate}`;\n\t\t}\n\n\t\t// Look for path-like match (e.g., \"features/auth\")\n\t\tconst pathMatch = evidence.find(e => e.includes(candidate));\n\t\tif (pathMatch) {\n\t\t\treturn `${srcBase}/${pathMatch.split('/')[0]}`;\n\t\t}\n\t}\n\n\t// Fallback to first candidate\n\treturn `${srcBase}/${candidates[0]}`;\n}\n\n/**\n * Calculate confidence scores from all detections.\n *\n * Overall confidence is the average of individual detector confidences.\n * Provides transparency into which aspects are well-detected vs uncertain.\n */\nfunction calculateConfidence(profile: ProjectProfile): ProposedConfig['confidence'] {\n\tconst framework = profile.framework.confidence;\n\tconst orm = profile.orm.confidence;\n\tconst architecture = profile.architecture.confidence;\n\tconst naming = Math.round(\n\t\t(profile.naming.fileCase.confidence + profile.naming.fileGrouping.confidence) / 2\n\t);\n\n\tconst overall = Math.round((framework + orm + architecture + naming) / 4);\n\n\treturn {\n\t\toverall,\n\t\tframework,\n\t\torm,\n\t\tarchitecture,\n\t\tnaming,\n\t};\n}\n","import { existsSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { detectFramework } from './framework-detector.js';\nimport { detectORM } from './orm-detector.js';\nimport { detectArchitecture } from './architecture-detector.js';\nimport { detectNaming } from './naming-detector.js';\nimport type { ProjectProfile, ScanOptions } from './types.js';\n\n/**\n * Find the src directory in a project.\n * Checks for common source directories: src/, app/, lib/\n */\nfunction findSrcDirectory(projectPath: string): string | null {\n\tconst candidates = ['src', 'app', 'lib'];\n\n\tfor (const candidate of candidates) {\n\t\tconst fullPath = join(projectPath, candidate);\n\t\ttry {\n\t\t\tconst stats = statSync(fullPath);\n\t\t\tif (stats.isDirectory()) {\n\t\t\t\treturn fullPath;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Directory doesn't exist, continue\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Scan a project and detect its patterns, conventions, and architecture.\n */\nexport async function scanProject(options: ScanOptions): Promise<ProjectProfile> {\n\tconst { directory } = options;\n\n\t// Validate directory exists\n\tif (!existsSync(directory)) {\n\t\tthrow new Error(`Directory not found: ${directory}`);\n\t}\n\n\t// Run all detectors in parallel for efficiency\n\tconst [framework, orm, architecture, naming] = await Promise.all([\n\t\tdetectFramework(directory),\n\t\tdetectORM(directory),\n\t\tdetectArchitecture(directory),\n\t\tdetectNaming(directory),\n\t]);\n\n\treturn {\n\t\tframework,\n\t\torm,\n\t\tarchitecture,\n\t\tnaming,\n\t\tpaths: {\n\t\t\troot: directory,\n\t\t\tsrc: findSrcDirectory(directory),\n\t\t},\n\t};\n}\n\nexport * from './types.js';\nexport * from './framework-detector.js';\nexport * from './orm-detector.js';\nexport * from './architecture-detector.js';\nexport * from './naming-detector.js';\nexport * from './config-generator.js';\n","/**\n * Context — shared CLI execution state.\n *\n * Loaded once per invocation and passed to every noun's summary/hints/commands.\n * Commands should not re-read config or re-run detection; use the Context.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport yaml from 'yaml';\nimport { scanProject } from '../../scanner/index.js';\nimport type { ProjectProfile } from '../../scanner/types.js';\n\nexport interface CodegenConfig {\n\tpaths?: {\n\t\tentities?: string;\n\t\tentities_dir?: string;\n\t\tsubsystems?: string;\n\t\tbackend_src?: string;\n\t\tfrontend_src?: string;\n\t\t/** Directory codegen writes barrel files into. Default: 'src/generated'. */\n\t\tgenerated?: string;\n\t};\n\tgenerate?: Record<string, unknown>;\n\tframework?: string;\n\torm?: string;\n\t[key: string]: unknown;\n}\n\nexport interface Context {\n\tcwd: string;\n\tconfigPath: string | null;\n\tconfig: CodegenConfig | null;\n\tisInitialized: boolean;\n\tframework: ProjectProfile | null;\n\tinstalledSubsystems: string[];\n\tentityCount: number;\n\tentitiesDir: string | null;\n\tjson: boolean;\n\tverbose: boolean;\n}\n\nexport interface LoadContextOptions {\n\tcwd?: string;\n\tconfigPath?: string;\n\tjson?: boolean;\n\tverbose?: boolean;\n\t/**\n\t * Skip scanner / subsystem detection. Useful for fast command paths\n\t * and tests that don't need full project analysis.\n\t */\n\tskipDetection?: boolean;\n}\n\n/**\n * Walk upward from `start` looking for a `codegen.config.yaml`. Returns the\n * absolute path or null if none is found before reaching the filesystem root.\n */\nfunction findConfigUpward(start: string): string | null {\n\tlet dir = path.resolve(start);\n\tconst root = path.parse(dir).root;\n\twhile (true) {\n\t\tconst candidate = path.join(dir, 'codegen.config.yaml');\n\t\tif (fs.existsSync(candidate)) return candidate;\n\t\tif (dir === root) return null;\n\t\tconst parent = path.dirname(dir);\n\t\tif (parent === dir) return null;\n\t\tdir = parent;\n\t}\n}\n\nfunction loadConfigFromPath(configPath: string): CodegenConfig | null {\n\ttry {\n\t\tconst content = fs.readFileSync(configPath, 'utf-8');\n\t\tconst parsed = yaml.parse(content);\n\t\tif (parsed && typeof parsed === 'object') {\n\t\t\treturn parsed as CodegenConfig;\n\t\t}\n\t\treturn null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction resolveEntitiesDir(cwd: string, config: CodegenConfig | null): string | null {\n\tconst fromConfig =\n\t\t(config?.paths?.entities as string | undefined) ??\n\t\t(config?.paths?.entities_dir as string | undefined);\n\tconst candidates: string[] = [];\n\tif (fromConfig) candidates.push(path.resolve(cwd, fromConfig));\n\tcandidates.push(path.resolve(cwd, 'entities'));\n\n\tfor (const c of candidates) {\n\t\tif (fs.existsSync(c) && fs.statSync(c).isDirectory()) return c;\n\t}\n\treturn null;\n}\n\nfunction countEntityYamls(entitiesDir: string | null): number {\n\tif (!entitiesDir || !fs.existsSync(entitiesDir)) return 0;\n\ttry {\n\t\treturn fs.readdirSync(entitiesDir).filter((f) => f.endsWith('.yaml') || f.endsWith('.yml'))\n\t\t\t.length;\n\t} catch {\n\t\treturn 0;\n\t}\n}\n\nconst KNOWN_SUBSYSTEMS = ['events', 'jobs', 'cache', 'storage'] as const;\n\n/**\n * Cheap subsystem detection — scans common install paths for a protocol file.\n * The richer {@link ../shared/subsystem-detect.ts} implementation returns\n * full metadata; loadContext() only needs names for the summary.\n */\nfunction detectInstalledSubsystemNames(\n\tcwd: string,\n\tconfig: CodegenConfig | null\n): string[] {\n\tconst configured = config?.paths?.subsystems as string | undefined;\n\tconst roots = [\n\t\t...(configured ? [path.resolve(cwd, configured)] : []),\n\t\tpath.resolve(cwd, 'src/shared/subsystems'),\n\t\tpath.resolve(cwd, 'src/subsystems'),\n\t\tpath.resolve(cwd, 'shared/subsystems'),\n\t];\n\n\tconst found = new Set<string>();\n\tfor (const root of roots) {\n\t\tif (!fs.existsSync(root)) continue;\n\t\tfor (const name of KNOWN_SUBSYSTEMS) {\n\t\t\tconst dir = path.join(root, name);\n\t\t\tif (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) continue;\n\t\t\tconst hasProtocol = fs\n\t\t\t\t.readdirSync(dir)\n\t\t\t\t.some((f) => f.endsWith('.protocol.ts'));\n\t\t\tif (hasProtocol) found.add(name);\n\t\t}\n\t}\n\treturn Array.from(found);\n}\n\nexport async function loadContext(overrides: LoadContextOptions = {}): Promise<Context> {\n\tconst cwd = overrides.cwd ? path.resolve(overrides.cwd) : process.cwd();\n\n\tconst explicit = overrides.configPath ? path.resolve(cwd, overrides.configPath) : null;\n\tconst configPath = explicit && fs.existsSync(explicit) ? explicit : findConfigUpward(cwd);\n\tconst config = configPath ? loadConfigFromPath(configPath) : null;\n\n\tconst entitiesDir = resolveEntitiesDir(cwd, config);\n\tconst entityCount = countEntityYamls(entitiesDir);\n\n\tconst isInitialized = Boolean(configPath) || entityCount > 0;\n\n\tlet framework: ProjectProfile | null = null;\n\tlet installedSubsystems: string[] = [];\n\n\tif (!overrides.skipDetection && isInitialized) {\n\t\ttry {\n\t\t\tframework = await scanProject({ directory: cwd });\n\t\t} catch {\n\t\t\tframework = null;\n\t\t}\n\t\tinstalledSubsystems = detectInstalledSubsystemNames(cwd, config);\n\t}\n\n\treturn {\n\t\tcwd,\n\t\tconfigPath,\n\t\tconfig,\n\t\tisInitialized,\n\t\tframework,\n\t\tinstalledSubsystems,\n\t\tentityCount,\n\t\tentitiesDir,\n\t\tjson: Boolean(overrides.json),\n\t\tverbose: Boolean(overrides.verbose),\n\t};\n}\n","/**\n * Semantic color tokens for the CLI.\n *\n * Commands reference tokens by role (`theme.success`, `theme.muted`), not literal\n * hex codes. A future dark/light toggle becomes a one-file change.\n *\n * See ADR-016 for rationale and palette choices.\n */\n\nimport chalk from 'chalk';\n\nexport const theme = {\n\tsuccess: chalk.hex('#A8D8A8'),\n\terror: chalk.hex('#FF8A80'),\n\twarning: chalk.hex('#FFD580'),\n\tsystem: chalk.hex('#A0D8EF'),\n\tagent: chalk.hex('#C4A7FF'),\n\tuser: chalk.hex('#D4A5C9'),\n\tmuted: chalk.hex('#888888'),\n\tdim: chalk.dim,\n} as const;\n\nexport type Theme = typeof theme;\n","/**\n * JSON mode state + structured output helper.\n *\n * When enabled, the UI helpers (printSuccess, withStatus, renderPane, renderHints)\n * short-circuit so commands can emit pure JSON without visual noise.\n */\n\nlet jsonMode = false;\n\nexport function setJsonMode(enabled: boolean): void {\n\tjsonMode = enabled;\n}\n\nexport function isJsonMode(): boolean {\n\treturn jsonMode;\n}\n\nexport function printJson(data: unknown): void {\n\tprocess.stdout.write(JSON.stringify(data, null, 2) + '\\n');\n}\n","/**\n * Pane primitives — border + content + optional footer.\n *\n * Nouns own the content layout; the pane module owns border, padding, and footer.\n * No-op in JSON mode.\n */\n\nimport { theme } from './theme.js';\nimport { isJsonMode } from './json.js';\n\nexport interface PaneOutput {\n\ttitle: string;\n\tbody: string | string[];\n\tfooter?: string;\n}\n\nfunction stripAnsi(s: string): string {\n\t// strip ANSI escape sequences for width calculations\n\treturn s.replace(/\\u001b\\[[0-9;]*m/g, '');\n}\n\nexport function renderPane(pane: PaneOutput): void {\n\tif (isJsonMode()) return;\n\n\tconst cols = process.stdout.columns ?? 80;\n\tconst width = Math.min(Math.max(40, cols), 80);\n\tconst titleLen = stripAnsi(pane.title).length;\n\tconst dashes = Math.max(0, width - titleLen - 5);\n\tconst top = '┌─ ' + pane.title + ' ' + '─'.repeat(dashes) + '┐';\n\tconst bot = '└' + '─'.repeat(Math.max(2, width - 2)) + '┘';\n\n\tconsole.log(theme.muted(top));\n\tconst lines = Array.isArray(pane.body) ? pane.body : pane.body.split('\\n');\n\tfor (const line of lines) {\n\t\tconsole.log(' ' + line);\n\t}\n\tif (pane.footer) {\n\t\tconsole.log('');\n\t\tconsole.log(theme.muted(' ' + pane.footer));\n\t}\n\tconsole.log(theme.muted(bot));\n}\n","/**\n * Hint row — suggested next commands rendered under a summary pane.\n *\n * No-op in JSON mode (nouns emit hints in the JSON payload instead).\n */\n\nimport { theme } from './theme.js';\nimport { isJsonMode } from './json.js';\n\nexport interface Hint {\n\tcommand: string;\n\tdescription: string;\n}\n\nexport function renderHints(hints: Hint[]): void {\n\tif (isJsonMode()) return;\n\tif (hints.length === 0) return;\n\n\tconsole.log('');\n\tconsole.log(theme.muted(' Next:'));\n\tconst maxCmd = Math.max(...hints.map((h) => h.command.length));\n\tfor (const h of hints) {\n\t\tconst pad = ' '.repeat(maxCmd - h.command.length + 2);\n\t\tconsole.log(` ${theme.system(h.command)}${pad}${theme.muted(h.description)}`);\n\t}\n}\n","/**\n * Icon glyphs with ASCII fallback for non-Unicode / non-TTY environments.\n *\n * Detection mirrors ADR-016: TTY present, TERM != 'dumb', not in CI.\n */\n\nconst unicode =\n\tBoolean(process.stdout.isTTY) && process.env.TERM !== 'dumb' && !process.env.CI;\n\nexport const icons = {\n\tsuccess: unicode ? '✓' : '[OK]',\n\terror: unicode ? '✗' : '[FAIL]',\n\twarning: unicode ? '⚠' : '[WARN]',\n\tinfo: unicode ? '◆' : '[INFO]',\n\tarrow: unicode ? '→' : '->',\n\tbullet: unicode ? '▸' : '>',\n\tcheck: unicode ? '✓' : '[x]',\n\tdash: unicode ? '◌' : '[ ]',\n} as const;\n\nexport type Icons = typeof icons;\n","import { z } from \"zod\";\n\n/**\n * Entity Definition Schema\n *\n * Generates backend code:\n * - Domain entity + repository interface\n * - Application DTOs, use-cases, queries\n * - Infrastructure Drizzle schema + repository\n * - Presentation controller\n * - NestJS module wiring\n * - Shared Zod schema in packages/db\n *\n * Generates frontend code:\n * - Entity metadata for automatic admin panels\n * - UI type, importance, grouping for fields\n */\n\n// ============================================================================\n// Field Types\n// ============================================================================\n\nconst FieldTypeSchema = z.enum([\n \"string\",\n \"integer\",\n \"decimal\",\n \"boolean\",\n \"uuid\",\n \"date\",\n \"datetime\",\n \"json\",\n \"entity_ref\", // Polymorphic reference: generates {field}EntityType + {field}EntityId columns\n \"string_array\", // Array of strings: generates text[] column\n \"enum\", // Enum type with choices or choices_from\n]);\n\nexport type FieldType = z.infer<typeof FieldTypeSchema>;\n\n// ============================================================================\n// UI Metadata Types\n// ============================================================================\n\nconst UiTypeSchema = z.enum([\n \"text\",\n \"textarea\",\n \"number\",\n \"money\",\n \"percentage\",\n \"email\",\n \"url\",\n \"date\",\n \"datetime\",\n \"boolean\",\n \"enum\",\n \"reference\",\n \"json\",\n \"badge\",\n \"password\",\n]);\n\nexport type UiType = z.infer<typeof UiTypeSchema>;\n\nconst UiImportanceSchema = z.enum([\"primary\", \"secondary\", \"tertiary\"]);\n\nexport type UiImportance = z.infer<typeof UiImportanceSchema>;\n\n/**\n * UI Metadata Schema - Optional field-level UI properties\n *\n * All properties are optional and will be inferred at generation time\n * if not explicitly specified in the YAML definition.\n */\n// ============================================================================\n// Semantic / Analytics Metadata Types\n// ============================================================================\n\nconst AnalyticsAggregationSchema = z.enum([\n 'sum',\n 'min',\n 'max',\n 'count',\n 'count_distinct',\n 'average',\n 'median',\n 'percentile',\n 'sum_boolean',\n]);\n\nconst AnalyticsDimensionTypeSchema = z.enum(['categorical', 'time']);\n\nconst AnalyticsEntityTypeSchema = z.enum(['primary', 'unique', 'foreign', 'natural']);\n\nconst AnalyticsTimeGranularitySchema = z.enum(['day', 'week', 'month', 'quarter', 'year']);\n\nconst AnalyticsVisibilitySchema = z.enum(['internal', 'agent', 'public']);\n\nconst NonAdditiveDimensionSchema = z.union([\n z.string(),\n z.object({\n name: z.string(),\n window_choice: z.string().optional(),\n window_groupings: z.array(z.string()).optional(),\n }),\n]);\n\n/**\n * Semantic Metadata Schema - Optional field-level analytics properties\n *\n * Controls how a field is exposed to the cube.js semantic layer:\n * measures, dimensions, entities, and their configuration.\n */\nconst SemanticMetadataSchema = z.object({\n measure: z.boolean().optional(),\n analytics_aggregation: AnalyticsAggregationSchema.optional(),\n agg_time_dimension: z.string().optional(),\n non_additive_dimension: NonAdditiveDimensionSchema.optional(),\n dimension: z.boolean().optional(),\n dimension_type: AnalyticsDimensionTypeSchema.optional(),\n time_granularity: AnalyticsTimeGranularitySchema.optional(),\n is_partition: z.boolean().optional(),\n entity: z.boolean().optional(),\n entity_type: AnalyticsEntityTypeSchema.optional(),\n entity_role: z.string().optional(),\n analytics_visibility: AnalyticsVisibilitySchema.optional(),\n semantic_expr: z.string().optional(),\n semantic_label: z.string().optional(),\n});\n\nconst UiMetadataSchema = z.object({\n ui_label: z.string().optional(),\n ui_type: UiTypeSchema.optional(),\n ui_importance: UiImportanceSchema.optional(),\n ui_group: z.string().optional(),\n ui_sortable: z.boolean().optional(),\n ui_filterable: z.boolean().optional(),\n ui_visible: z.boolean().optional(),\n ui_placeholder: z.string().optional(),\n ui_help: z.string().optional(),\n ui_format: z.record(z.unknown()).optional(),\n});\n\n// ============================================================================\n// Field Definition\n// ============================================================================\n\n/**\n * Field Definition Schema\n *\n * Semantics:\n * - `required: true` → Field must be provided on CREATE (DTO validation)\n * - `required: false` → Field is optional on CREATE (DTO validation)\n * - `nullable: true` → Database column allows NULL\n * - `nullable: false` (default) → Database column is NOT NULL\n *\n * Common patterns:\n * - `required: true` (nullable defaults to false) → Must provide, cannot be null\n * - `required: false, nullable: true` → Optional field, can be null\n * - `required: true, nullable: true` → INVALID (rejected by validator)\n * - `required: false, nullable: false` → Has default value in DB\n */\n/**\n * Base Field Schema - Core database/type properties\n */\nconst BaseFieldSchema = z.object({\n type: FieldTypeSchema,\n required: z.boolean().optional().default(false),\n nullable: z.boolean().optional().default(false),\n\n // String constraints\n max_length: z.number().int().positive().optional(),\n min_length: z.number().int().nonnegative().optional(),\n\n // Numeric constraints\n min: z.number().optional(),\n max: z.number().optional(),\n\n // Enum/choices (inline definition)\n choices: z.array(z.string()).optional(),\n\n // Enum/choices from external file (e.g., \"relationship_types.yaml\")\n // Mutually exclusive with choices - parser loads file and extracts keys\n choices_from: z.string().optional(),\n\n // Entity reference: allowed entity types for polymorphic refs\n // Required when type is 'entity_ref'\n allowed_types: z.array(z.string()).optional(),\n\n // Default value\n default: z.unknown().optional(),\n\n // Indexing\n index: z.boolean().optional(),\n unique: z.boolean().optional(),\n\n // Foreign key reference (e.g., \"accounts.id\")\n foreign_key: z.string().optional(),\n});\n\n/**\n * Field Definition Schema - Combines base fields with optional UI metadata\n */\nconst FieldDefinitionSchema = BaseFieldSchema.merge(UiMetadataSchema).merge(SemanticMetadataSchema)\n .refine((data) => !(data.required === true && data.nullable === true), {\n message:\n \"'required: true' and 'nullable: true' cannot both be set. A required field cannot be null.\",\n path: [\"required\"],\n })\n .refine(\n (data) => {\n if (data.min_length !== undefined && data.type !== \"string\") {\n return false;\n }\n return true;\n },\n {\n message: \"'min_length' can only be used with type 'string'\",\n path: [\"min_length\"],\n },\n )\n .refine(\n (data) => {\n if (data.max_length !== undefined && data.type !== \"string\") {\n return false;\n }\n return true;\n },\n {\n message: \"'max_length' can only be used with type 'string'\",\n path: [\"max_length\"],\n },\n )\n .refine(\n (data) => {\n if (\n data.min !== undefined &&\n ![\"integer\", \"decimal\"].includes(data.type)\n ) {\n return false;\n }\n return true;\n },\n {\n message: \"'min' can only be used with numeric types\",\n path: [\"min\"],\n },\n )\n .refine(\n (data) => {\n if (\n data.max !== undefined &&\n ![\"integer\", \"decimal\"].includes(data.type)\n ) {\n return false;\n }\n return true;\n },\n {\n message: \"'max' can only be used with numeric types\",\n path: [\"max\"],\n },\n )\n .refine(\n (data) => {\n // entity_ref requires allowed_types\n if (data.type === \"entity_ref\" && !data.allowed_types?.length) {\n return false;\n }\n return true;\n },\n {\n message: \"'entity_ref' type requires 'allowed_types' to be specified\",\n path: [\"allowed_types\"],\n },\n )\n .refine(\n (data) => {\n // allowed_types only valid for entity_ref\n if (data.allowed_types !== undefined && data.type !== \"entity_ref\") {\n return false;\n }\n return true;\n },\n {\n message: \"'allowed_types' can only be used with type 'entity_ref'\",\n path: [\"allowed_types\"],\n },\n )\n .refine(\n (data) => {\n // choices and choices_from are mutually exclusive\n if (data.choices !== undefined && data.choices_from !== undefined) {\n return false;\n }\n return true;\n },\n {\n message: \"'choices' and 'choices_from' cannot both be specified\",\n path: [\"choices_from\"],\n },\n )\n .refine(\n (data) => {\n // enum type requires either choices or choices_from\n if (data.type === \"enum\" && !data.choices?.length && !data.choices_from) {\n return false;\n }\n return true;\n },\n {\n message: \"'enum' type requires either 'choices' or 'choices_from'\",\n path: [\"choices\"],\n },\n )\n .refine(\n (data) => {\n // If measure is true, analytics_aggregation must be present\n if (data.measure === true && !data.analytics_aggregation) {\n return false;\n }\n return true;\n },\n {\n message:\n \"When 'measure' is true, 'analytics_aggregation' must be specified\",\n path: [\"analytics_aggregation\"],\n },\n );\n\nexport type FieldDefinition = z.infer<typeof FieldDefinitionSchema>;\n\n// ============================================================================\n// Relationship Definition\n// ============================================================================\n\nconst RelationshipTypeSchema = z.enum([\"belongs_to\", \"has_many\", \"has_one\"]);\n\nconst RelationshipSchema = z\n .object({\n type: RelationshipTypeSchema,\n target: z.string(), // Target entity name (e.g., \"account\")\n foreign_key: z.string(), // FK field name (e.g., \"account_id\")\n through: z.string().optional(), // For transitive: \"owned_opportunities.updates\"\n inverse: z.string().optional(), // Name of inverse relationship on target entity\n })\n .strict();\n\nexport type Relationship = z.infer<typeof RelationshipSchema>;\n\n// ============================================================================\n// Behavior Configuration\n// ============================================================================\n\n/**\n * Behavior configuration can be:\n * - A simple string: \"timestamps\"\n * - An object with options: { name: \"sluggable\", options: { source: \"title\" } }\n *\n * Built-in behaviors:\n * - timestamps: Adds created_at, updated_at fields\n * - soft_delete: Adds deleted_at field, filters deleted records\n * - user_tracking: Adds created_by, updated_by fields\n * - temporal_validity: Adds valid_from, valid_to, is_active fields\n * with deactivate() method and validity-aware query filtering\n */\nconst BehaviorConfigSchema = z.union([\n z.string(),\n z.object({\n name: z.string(),\n options: z.record(z.unknown()).optional(),\n }),\n]);\n\nexport type BehaviorConfig = z.infer<typeof BehaviorConfigSchema>;\n\n/**\n * Behavior strategy for repository code generation\n * - base_class: Extend BaseRepository (DRY, recommended)\n * - inline: Generate all code directly (WET, full transparency)\n */\nconst BehaviorStrategySchema = z.enum([\"base_class\", \"inline\"]);\n\nexport type BehaviorStrategy = z.infer<typeof BehaviorStrategySchema>;\n\n// ============================================================================\n// Entity Configuration\n// ============================================================================\n\n/**\n * Layout: Folder structure - controls directory nesting\n * - nested: domain/opportunity/opportunity.entity.ts\n * - flat: domain/opportunity.entity.ts\n */\nconst FolderStructureSchema = z.enum([\"nested\", \"flat\"]).default(\"nested\");\n\n/**\n * Layout: File grouping - controls how related code is organized\n * - separate: Each concern in its own file (entity.ts, repository.interface.ts)\n * - grouped: Related concerns combined into index.ts\n *\n * This is orthogonal to folder_structure:\n * | folder_structure | file_grouping | Result |\n * |-----------------|---------------|--------|\n * | nested | separate | domain/opportunity/opportunity.entity.ts |\n * | nested | grouped | domain/opportunity/index.ts (combined) |\n * | flat | separate | domain/opportunity.entity.ts |\n * | flat | grouped | domain/opportunity.ts (combined) |\n */\nconst FileGroupingSchema = z.enum([\"separate\", \"grouped\"]).default(\"separate\");\n\n/**\n * Expose configuration - which layers to generate for this entity\n * - repository: Always generated (domain entity, repository interface/impl)\n * - rest: Generate REST controller\n * - trpc: Generate tRPC module\n * - electric: Generate Electric SQL migration (REPLICA IDENTITY + publication)\n *\n * Default: ['repository', 'rest', 'trpc'] (all layers)\n */\nconst ExposeLayerSchema = z.enum([\"repository\", \"rest\", \"trpc\", \"electric\"]);\nexport type ExposeLayer = z.infer<typeof ExposeLayerSchema>;\n\nconst EntityConfigSchema = z\n .object({\n name: z\n .string()\n .regex(\n /^[a-z][a-z0-9_]*$/,\n \"Entity name must be lowercase with underscores (e.g., 'opportunity')\",\n ),\n plural: z.string().regex(/^[a-z][a-z0-9_]*$/, \"Plural must be lowercase\"),\n table: z.string().regex(/^[a-z][a-z0-9_]*$/, \"Table must be lowercase\"),\n\n // Layout options (orthogonal concerns)\n // folder_structure: controls directory nesting\n // file_grouping: controls file organization\n folder_structure: FolderStructureSchema.optional(),\n file_grouping: FileGroupingSchema.optional(),\n\n // Per-entity behavior strategy override (overrides codegen.config.yaml)\n behavior_strategy: BehaviorStrategySchema.optional(),\n // Which layers to generate (default: all)\n expose: z\n .array(ExposeLayerSchema)\n .optional()\n .default([\"repository\", \"rest\", \"trpc\"]),\n\n // v2: Entity family classification (ADR-005)\n // Determines which base class hierarchy the entity inherits from\n family: z\n .enum([\"base\", \"synced\", \"activity\", \"knowledge\", \"metadata\"])\n .optional(),\n })\n .strict();\n\nexport type EntityConfig = z.infer<typeof EntityConfigSchema>;\n\n// ============================================================================\n// Query Declaration\n// ============================================================================\n\n/**\n * Query Declaration Schema - Declarative query generation (ADR-005)\n *\n * Each declaration generates repository + service + use case methods.\n *\n * Examples:\n * { by: [\"user_id\"] }\n * { by: [\"email\"], unique: true }\n * { by: [\"account_id\"], order: \"created_at desc\", limit: true }\n * { by: [\"opportunity_id\"], select: [\"email\"], via: \"opportunity_contact_link\" }\n */\nconst QueryDeclarationSchema = z.object({\n by: z.array(z.string()).min(1),\n unique: z.boolean().optional(),\n select: z.array(z.string()).optional(),\n order: z.string().optional(),\n limit: z.boolean().optional(),\n via: z.string().optional(),\n});\n\nexport type QueryDeclaration = z.infer<typeof QueryDeclarationSchema>;\n\n// ============================================================================\n// Sync Configuration\n// ============================================================================\n\n/**\n * Direction of sync with an external provider\n */\nexport const SyncDirectionSchema = z.enum([\n 'inbound',\n 'outbound',\n 'bidirectional',\n]);\n\nexport type SyncDirection = z.infer<typeof SyncDirectionSchema>;\n\n/**\n * Per-provider sync configuration\n */\nexport const ProviderSyncSchema = z.object({\n remote_entity: z.string(),\n direction: SyncDirectionSchema,\n cdc: z.boolean().optional().default(false),\n field_mapping: z.record(z.string(), z.string()).optional(),\n read_only_fields: z.array(z.string()).optional(),\n});\n\nexport type ProviderSync = z.infer<typeof ProviderSyncSchema>;\n\n/**\n * Top-level sync block: Electric SQL + named provider configs\n */\nexport const SyncConfigSchema = z.object({\n electric: z.boolean().optional().default(false),\n providers: z.record(z.string(), ProviderSyncSchema).optional(),\n});\n\nexport type SyncConfig = z.infer<typeof SyncConfigSchema>;\n\n// ============================================================================\n// Event Declaration\n// ============================================================================\n\n/**\n * Event Declaration Schema - Domain event declarations (CODEGEN-EVOLUTION-PLAN Phase 2)\n *\n * Each declaration generates typed event classes, handlers, and queue registration.\n *\n * Example:\n * name: opportunity_stage_changed\n * queue: domain-events\n * body:\n * opportunity_id: uuid\n * old_stage: string\n * generate_handler: true\n */\nconst EventDeclarationSchema = z.object({\n name: z\n .string()\n .regex(/^[a-z][a-z0-9_]*$/, \"Event name must be snake_case\"),\n queue: z.string(),\n body: z.record(z.string(), z.string()),\n generate_handler: z.boolean().optional().default(false),\n});\n\nexport type EventDeclaration = z.infer<typeof EventDeclarationSchema>;\n\n// ============================================================================\n// Analytics Block (entity-level)\n// ============================================================================\n\n/**\n * Simple metric in a YAML metric definition\n */\nconst SimpleMetricSchema = z.object({\n type: z.literal('simple'),\n measure: z.string(),\n agg: AnalyticsAggregationSchema.optional(),\n filter: z.string().optional(),\n description: z.string().optional(),\n label: z.string().optional(),\n});\n\n/**\n * Derived metric — expression combining other metrics\n */\nconst DerivedMetricSchema = z.object({\n type: z.literal('derived'),\n expr: z.string(),\n metrics: z.array(z.string()),\n description: z.string().optional(),\n label: z.string().optional(),\n});\n\n/**\n * Ratio metric — numerator / denominator\n */\nconst RatioMetricSchema = z.object({\n type: z.literal('ratio'),\n numerator: z.union([z.string(), SimpleMetricSchema]),\n denominator: z.union([z.string(), SimpleMetricSchema]),\n filter: z.string().optional(),\n description: z.string().optional(),\n label: z.string().optional(),\n});\n\n/**\n * Cumulative metric — time-series accumulation\n */\nconst CumulativeMetricSchema = z.object({\n type: z.literal('cumulative'),\n measure: z.string(),\n window: z.string().optional(),\n grain_to_date: AnalyticsTimeGranularitySchema.optional(),\n description: z.string().optional(),\n label: z.string().optional(),\n});\n\n/**\n * Discriminated union of all four metric types\n */\nconst MetricDefinitionSchema = z.discriminatedUnion('type', [\n SimpleMetricSchema,\n DerivedMetricSchema,\n RatioMetricSchema,\n CumulativeMetricSchema,\n]);\n\nexport type MetricDefinition = z.infer<typeof MetricDefinitionSchema>;\n\n/**\n * Entity-level analytics block\n *\n * Declared in the YAML under `analytics:` alongside fields and relationships.\n */\nconst AnalyticsBlockSchema = z.object({\n measure_packs: z.array(z.string()).optional(),\n cube_name: z.string().optional(),\n metrics: z.record(z.string(), MetricDefinitionSchema).optional(),\n});\n\nexport type AnalyticsBlock = z.infer<typeof AnalyticsBlockSchema>;\n\n// ============================================================================\n// Full Entity Definition\n// ============================================================================\n\nexport const EntityDefinitionSchema = z\n .object({\n entity: EntityConfigSchema,\n fields: z.record(z.string(), FieldDefinitionSchema),\n relationships: z.record(z.string(), RelationshipSchema).optional(),\n // Behaviors add cross-cutting concerns (timestamps, soft_delete, user_tracking, etc.)\n behaviors: z.array(BehaviorConfigSchema).optional().default([]),\n\n // v2: Declarative query generation (ADR-005)\n // Generates repository + service + use case methods from declarations\n queries: z.array(QueryDeclarationSchema).optional(),\n\n // v2: Integration sync configuration (CODEGEN-EVOLUTION-PLAN Phase 2)\n // Electric SQL + provider sync (Salesforce, HubSpot, etc.)\n sync: SyncConfigSchema.optional(),\n\n // v2: Domain event declarations (CODEGEN-EVOLUTION-PLAN Phase 2)\n // Generates typed event classes, handlers, and queue registration\n events: z.array(EventDeclarationSchema).optional(),\n\n // v2: Analytics / semantic layer configuration\n // Cube.js measure packs, custom cube name, and metric definitions\n analytics: AnalyticsBlockSchema.optional(),\n })\n .strict();\n\nexport type EntityDefinition = z.infer<typeof EntityDefinitionSchema>;\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\nexport function validateEntityDefinition(data: unknown): EntityDefinition {\n return EntityDefinitionSchema.parse(data);\n}\n\nexport function safeValidateEntityDefinition(data: unknown): {\n success: boolean;\n data?: EntityDefinition;\n error?: z.ZodError;\n} {\n const result = EntityDefinitionSchema.safeParse(data);\n if (result.success) {\n return { success: true, data: result.data };\n }\n return { success: false, error: result.error };\n}\n\n// ============================================================================\n// Type Mapping Utilities (for code generation)\n// ============================================================================\n\n/**\n * Maps YAML field types to TypeScript types\n *\n * Note: 'entity_ref' is handled specially in templates as it generates\n * two fields: {field}EntityType (EntityType enum) and {field}EntityId (string)\n */\nexport const fieldTypeToTypeScript: Record<FieldType, string> = {\n string: \"string\",\n integer: \"number\",\n decimal: \"number\",\n boolean: \"boolean\",\n uuid: \"string\",\n date: \"Date\",\n datetime: \"Date\",\n json: \"unknown\",\n entity_ref: \"EntityRef\", // Placeholder - templates handle specially\n string_array: \"string[]\",\n enum: \"string\", // Actual enum type generated from choices\n};\n\n/**\n * Maps YAML field types to Drizzle column types\n *\n * Note: 'entity_ref' generates two columns: pgEnum + uuid\n * Note: 'enum' uses pgEnum with choices\n */\nexport const fieldTypeToDrizzle: Record<FieldType, string> = {\n string: \"varchar\",\n integer: \"integer\",\n decimal: \"decimal\",\n boolean: \"boolean\",\n uuid: \"uuid\",\n date: \"date\",\n datetime: \"timestamp\",\n json: \"jsonb\",\n entity_ref: \"entity_ref\", // Placeholder - templates handle specially (enum + uuid)\n string_array: \"text().array()\",\n enum: \"enum\", // Placeholder - templates generate pgEnum\n};\n\n/**\n * Maps YAML field types to Zod schema methods\n *\n * Note: 'entity_ref' generates two fields in Zod schema\n * Note: 'enum' uses z.enum() with choices\n */\nexport const fieldTypeToZod: Record<FieldType, string> = {\n string: \"z.string()\",\n integer: \"z.number().int()\",\n decimal: \"z.number()\",\n boolean: \"z.boolean()\",\n uuid: \"z.string().uuid()\",\n date: \"z.date()\",\n datetime: \"z.date()\",\n json: \"z.unknown()\",\n entity_ref: \"entity_ref\", // Placeholder - templates handle specially\n string_array: \"z.array(z.string())\",\n enum: \"z.enum()\", // Placeholder - templates add choices\n};\n","import { z } from 'zod';\n\n/**\n * Relationship Definition Schema\n *\n * Defines the YAML contract for first-class relationship entities — typed,\n * temporal, sourced junction tables between core entities.\n *\n * A relationship definition generates the same artifacts as an entity\n * (Drizzle schema, repository, DTOs, NestJS module, controller) but with\n * auto-generated FK columns, type enum, temporal fields, and source tracking.\n *\n * The relationship: block replaces entity: as the top-level discriminator.\n * The fields:, queries:, and behaviors: blocks reuse entity-definition schemas.\n *\n * See: docs/codegen-evolution-data-model/03-relationship-taxonomy.md\n * See: test/fixtures/relationships/ for examples\n */\n\n// Re-use field and query schemas from entity-definition\n// These are imported to avoid duplication — fields on a relationship\n// work identically to fields on an entity.\nimport type { FieldDefinition, QueryDeclaration } from './entity-definition.schema.js';\n\n// ============================================================================\n// Relationship Type Definitions\n// ============================================================================\n\n/**\n * Direction metadata for a single relationship type.\n *\n * Required for self-referential relationships (person↔person, org↔org)\n * where direction can't be inferred from entity-type asymmetry.\n *\n * Three mutually exclusive modes:\n * - inverse: \"from→to is called X, to→from is called Y\"\n * - bidirectional: true — direction doesn't matter, query both sides\n * - directed: true — one-way, no inverse name (default if none specified)\n */\nconst TypeDirectionSchema = z\n\t.object({\n\t\t/** Name of the inverse type when viewed from the other direction */\n\t\tinverse: z.string().optional(),\n\t\t/** Both directions are equivalent — queries should check both FK columns */\n\t\tbidirectional: z.boolean().optional(),\n\t\t/** Explicitly directed, no named inverse (default behavior) */\n\t\tdirected: z.boolean().optional(),\n\t})\n\t.refine(\n\t\t(data) => {\n\t\t\tconst set = [data.inverse, data.bidirectional, data.directed].filter(\n\t\t\t\t(v) => v !== undefined,\n\t\t\t);\n\t\t\treturn set.length === 1;\n\t\t},\n\t\t{\n\t\t\tmessage:\n\t\t\t\t'Exactly one of inverse, bidirectional, or directed must be specified',\n\t\t},\n\t);\n\nexport type TypeDirection = z.infer<typeof TypeDirectionSchema>;\n\n/**\n * Relationship types can be declared in two forms:\n *\n * 1. Simple list — for cross-type relationships where direction is\n * unambiguous from entity asymmetry:\n * types: [employed_by, advises, board_member]\n *\n * 2. Object map — for self-referential or when types need direction metadata:\n * types:\n * reporting:\n * inverse: management\n * network:\n * bidirectional: true\n *\n * The simple list is sugar for \"all directed from→to, no inverses.\"\n */\nconst RelationshipTypesSchema = z.union([\n\t// Simple list: all types are directed from→to\n\tz.array(z.string().regex(/^[a-z][a-z0-9_]*$/, 'Type must be snake_case')),\n\t// Object map: each type has direction metadata\n\tz.record(\n\t\tz.string().regex(/^[a-z][a-z0-9_]*$/, 'Type key must be snake_case'),\n\t\tTypeDirectionSchema,\n\t),\n]);\n\nexport type RelationshipTypes = z.infer<typeof RelationshipTypesSchema>;\n\n// ============================================================================\n// On-Delete Semantics (ADR-021)\n// ============================================================================\n\nconst OnDeleteActionSchema = z\n\t.enum(['restrict', 'cascade', 'set_null', 'no_action'])\n\t.default('restrict');\n\nexport type OnDeleteAction = z.infer<typeof OnDeleteActionSchema>;\n\n// ============================================================================\n// Relationship Configuration Block\n// ============================================================================\n\n/**\n * The relationship: block — top-level config for a relationship definition.\n *\n * Establishes the two endpoints, type taxonomy, and behavioral flags.\n * Auto-generates FK columns, type enum, temporal fields, source tracking,\n * and timestamps based on configuration.\n */\nconst RelationshipConfigSchema = z\n\t.object({\n\t\t/** Relationship name (snake_case). Used for class/file naming. */\n\t\tname: z.string().regex(\n\t\t\t/^[a-z][a-z0-9_]*$/,\n\t\t\t'Relationship name must be snake_case',\n\t\t),\n\n\t\t/** Database table name. Defaults to {name}s if not specified. */\n\t\ttable: z\n\t\t\t.string()\n\t\t\t.regex(/^[a-z][a-z0-9_]*$/, 'Table must be snake_case')\n\t\t\t.optional(),\n\n\t\t/** The \"from\" entity — generates {entity}_id FK column (subject). */\n\t\tfrom: z.string().regex(/^[a-z][a-z0-9_]*$/, 'Entity name must be snake_case'),\n\n\t\t/** The \"to\" entity — generates {entity}_id FK column (object). */\n\t\tto: z.string().regex(/^[a-z][a-z0-9_]*$/, 'Entity name must be snake_case'),\n\n\t\t/**\n\t\t * Relationship subtypes. Optional — omit for untyped junctions.\n\t\t * When present, generates a `type` enum column on the junction table.\n\t\t *\n\t\t * Simple list: all types are directed (from→to). Use for cross-type\n\t\t * relationships where entity asymmetry makes direction obvious.\n\t\t *\n\t\t * Object map: each type declares its own direction metadata.\n\t\t * Required for self-referential relationships (from === to).\n\t\t */\n\t\ttypes: RelationshipTypesSchema.optional(),\n\n\t\t/**\n\t\t * Generate temporal validity fields: valid_from (date), valid_to (date?),\n\t\t * is_current (boolean, denormalized for query performance).\n\t\t * Default: true\n\t\t */\n\t\ttemporal: z.boolean().default(true),\n\n\t\t/**\n\t\t * Generate source tracking fields: source (enum), confidence (decimal 0-1).\n\t\t * Default: true\n\t\t */\n\t\tsourced: z.boolean().default(true),\n\n\t\t/** on_delete action for the \"from\" endpoint FK. Default: restrict */\n\t\ton_delete_from: OnDeleteActionSchema.optional(),\n\n\t\t/** on_delete action for the \"to\" endpoint FK. Default: restrict */\n\t\ton_delete_to: OnDeleteActionSchema.optional(),\n\n\t\t/**\n\t\t * Override the default unique constraint columns.\n\t\t *\n\t\t * Defaults:\n\t\t * - Typed: [from_id, to_id, type]\n\t\t * - Typed + temporal: [from_id, to_id, type, valid_from]\n\t\t * - Untyped: [from_id, to_id]\n\t\t *\n\t\t * Use this when the default doesn't fit — e.g., allowing multiple\n\t\t * relationships of the same type between the same entities at different times.\n\t\t */\n\t\tunique_on: z.array(z.string()).optional(),\n\t})\n\t.strict();\n\nexport type RelationshipConfig = z.infer<typeof RelationshipConfigSchema>;\n\n// ============================================================================\n// Query Declaration (reuse from entity-definition)\n// ============================================================================\n\n/**\n * Same query declaration syntax as entities.\n * FK field names in `by:` use the auto-generated names:\n * - Cross-type: {entity}_id (e.g., person_id, organization_id)\n * - Self-referential: from_{entity}_id, to_{entity}_id\n */\nconst RelationshipQuerySchema = z.object({\n\tby: z.array(z.string()).min(1),\n\tunique: z.boolean().optional(),\n\tselect: z.array(z.string()).optional(),\n\torder: z.string().optional(),\n\tlimit: z.boolean().optional(),\n});\n\n// ============================================================================\n// Field Definition (reuse from entity-definition)\n// ============================================================================\n\n// We import the type but need to re-reference the schema inline for Zod parsing.\n// The actual FieldDefinitionSchema is defined in entity-definition.schema.ts.\n// For now, we use z.record(z.string(), z.any()) and validate fields\n// through the shared FieldDefinitionSchema at parse time.\n//\n// TODO: Extract FieldDefinitionSchema to a shared module so both\n// entity-definition and relationship-definition can import it directly.\n\n// ============================================================================\n// Full Relationship Definition\n// ============================================================================\n\n/**\n * Complete relationship definition — the top-level shape of a relationship YAML file.\n *\n * Example (minimal):\n * relationship:\n * name: engagement_opportunity\n * from: engagement\n * to: opportunity\n *\n * Example (full):\n * relationship:\n * name: person_organization\n * table: person_organizations\n * from: person\n * to: organization\n * types: [employed_by, advises, board_member]\n * temporal: true\n * sourced: true\n * fields:\n * role_title:\n * type: string\n * nullable: true\n * queries:\n * - by: [person_id]\n */\nexport const RelationshipDefinitionSchema = z\n\t.object({\n\t\t/** Relationship configuration block */\n\t\trelationship: RelationshipConfigSchema,\n\n\t\t/**\n\t\t * Additional fields beyond auto-generated ones.\n\t\t * These describe the relationship, not either endpoint entity.\n\t\t * Uses the same field definition schema as entity fields.\n\t\t */\n\t\tfields: z.record(z.string(), z.any()).optional(),\n\n\t\t/** Declarative queries — same syntax as entity queries. */\n\t\tqueries: z.array(RelationshipQuerySchema).optional(),\n\t})\n\t.strict()\n\t.refine(\n\t\t(data) => {\n\t\t\t// Self-referential relationships with types MUST use the object map form\n\t\t\t// so that direction metadata (inverse/bidirectional/directed) is explicit.\n\t\t\tif (data.relationship.from === data.relationship.to && data.relationship.types) {\n\t\t\t\treturn !Array.isArray(data.relationship.types);\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t\t{\n\t\t\tmessage:\n\t\t\t\t'Self-referential relationships must use the object map form for types ' +\n\t\t\t\t'(with inverse/bidirectional/directed metadata), not a simple list',\n\t\t\tpath: ['relationship', 'types'],\n\t\t},\n\t)\n\t.refine(\n\t\t(data) => {\n\t\t\t// Reject fields: keys that collide with auto-generated column names.\n\t\t\t// The reserved set is dynamic — depends on the relationship config.\n\t\t\tif (!data.fields) return true;\n\n\t\t\tconst reserved = getReservedColumnNames(data.relationship);\n\t\t\tconst collisions = Object.keys(data.fields).filter((key) =>\n\t\t\t\treserved.has(key),\n\t\t\t);\n\t\t\treturn collisions.length === 0;\n\t\t},\n\t\t{\n\t\t\tmessage:\n\t\t\t\t'fields: contains keys that collide with auto-generated columns. ' +\n\t\t\t\t'Reserved names depend on config (type, valid_from, valid_to, ' +\n\t\t\t\t'is_current, source, confidence, id, created_at, updated_at, and FK columns).',\n\t\t\tpath: ['fields'],\n\t\t},\n\t);\n\nexport type RelationshipDefinition = z.infer<\n\ttypeof RelationshipDefinitionSchema\n>;\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\nexport function validateRelationshipDefinition(\n\tdata: unknown,\n): RelationshipDefinition {\n\treturn RelationshipDefinitionSchema.parse(data);\n}\n\nexport function safeValidateRelationshipDefinition(data: unknown): {\n\tsuccess: boolean;\n\tdata?: RelationshipDefinition;\n\terror?: z.ZodError;\n} {\n\tconst result = RelationshipDefinitionSchema.safeParse(data);\n\tif (result.success) {\n\t\treturn { success: true, data: result.data };\n\t}\n\treturn { success: false, error: result.error };\n}\n\n// ============================================================================\n// Reserved Column Names\n// ============================================================================\n\n/**\n * Returns the set of column names that are auto-generated for a relationship\n * and therefore cannot be used as custom field names.\n *\n * The set is dynamic — it depends on the relationship config:\n * - Always: id, created_at, updated_at, and both FK columns\n * - If types: present → type\n * - If temporal: true → valid_from, valid_to, is_current\n * - If sourced: true → source, confidence\n */\nexport function getReservedColumnNames(config: RelationshipConfig): Set<string> {\n\tconst { fromColumn, toColumn } = deriveRelationshipFKColumns(config);\n\tconst reserved = new Set([\n\t\t'id',\n\t\t'created_at',\n\t\t'updated_at',\n\t\tfromColumn,\n\t\ttoColumn,\n\t]);\n\n\tif (config.types) {\n\t\treserved.add('type');\n\t}\n\tif (config.temporal) {\n\t\treserved.add('valid_from');\n\t\treserved.add('valid_to');\n\t\treserved.add('is_current');\n\t}\n\tif (config.sourced) {\n\t\treserved.add('source');\n\t\treserved.add('confidence');\n\t}\n\n\treturn reserved;\n}\n\n// ============================================================================\n// Auto-Generated Field Helpers\n// ============================================================================\n\n/**\n * Derives the FK column names for a relationship.\n *\n * Cross-type (from !== to):\n * from: person, to: organization → person_id, organization_id\n *\n * Self-referential (from === to):\n * from: person, to: person → from_person_id, to_person_id\n */\nexport function deriveRelationshipFKColumns(config: RelationshipConfig): {\n\tfromColumn: string;\n\ttoColumn: string;\n} {\n\tif (config.from === config.to) {\n\t\treturn {\n\t\t\tfromColumn: `from_${config.from}_id`,\n\t\t\ttoColumn: `to_${config.to}_id`,\n\t\t};\n\t}\n\treturn {\n\t\tfromColumn: `${config.from}_id`,\n\t\ttoColumn: `${config.to}_id`,\n\t};\n}\n\n/**\n * Derives the default table name if not explicitly specified.\n * Uses the relationship name + 's' suffix.\n */\nexport function deriveTableName(config: RelationshipConfig): string {\n\treturn config.table ?? `${config.name}s`;\n}\n\n/**\n * Collects all type names from a types declaration.\n * Handles both simple list and object map forms.\n */\nexport function collectTypeNames(\n\ttypes: RelationshipTypes | undefined,\n): string[] {\n\tif (!types) return [];\n\tif (Array.isArray(types)) return types;\n\treturn Object.keys(types);\n}\n\n/**\n * Collects all inverse type names from a types declaration.\n * Only applicable for object map form with inverse metadata.\n */\nexport function collectInverseNames(\n\ttypes: RelationshipTypes | undefined,\n): string[] {\n\tif (!types || Array.isArray(types)) return [];\n\treturn Object.values(types)\n\t\t.map((dir) => (dir as TypeDirection & { inverse?: string }).inverse)\n\t\t.filter((v): v is string => v !== undefined);\n}\n\n/**\n * Determines the default unique constraint columns.\n *\n * Logic:\n * - Typed + temporal: [from_id, to_id, type, valid_from]\n * - Typed: [from_id, to_id, type]\n * - Untyped: [from_id, to_id]\n */\nexport function deriveUniqueConstraint(config: RelationshipConfig): string[] {\n\tif (config.unique_on) return config.unique_on;\n\n\tconst { fromColumn, toColumn } = deriveRelationshipFKColumns(config);\n\tconst columns = [fromColumn, toColumn];\n\n\tif (config.types) {\n\t\tcolumns.push('type');\n\t}\n\tif (config.temporal && config.types) {\n\t\tcolumns.push('valid_from');\n\t}\n\n\treturn columns;\n}\n","import { readFileSync, existsSync } from 'node:fs';\nimport { parse as parseYaml } from 'yaml';\nimport { ZodError } from 'zod';\nimport {\n\ttype EntityDefinition,\n\tEntityDefinitionSchema,\n} from '../schema/entity-definition.schema';\nimport {\n\ttype RelationshipDefinition,\n\tRelationshipDefinitionSchema,\n} from '../schema/relationship-definition.schema';\n\nexport interface LoadResult {\n\tsuccess: true;\n\tdefinition: EntityDefinition;\n\tfilePath: string;\n}\n\nexport interface LoadError {\n\tsuccess: false;\n\terror: string;\n\tdetails?: string[];\n\tfilePath: string;\n}\n\nexport type LoadEntityResult = LoadResult | LoadError;\n\n/**\n * Load and validate an entity definition from a YAML file\n */\nexport function loadEntityFromYaml(filePath: string): LoadEntityResult {\n\t// Check file exists\n\tif (!existsSync(filePath)) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: `File not found: ${filePath}`,\n\t\t\tfilePath,\n\t\t};\n\t}\n\n\t// Read file\n\tlet content: string;\n\ttry {\n\t\tcontent = readFileSync(filePath, 'utf-8');\n\t} catch (err) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: `Failed to read file: ${filePath}`,\n\t\t\tdetails: [err instanceof Error ? err.message : String(err)],\n\t\t\tfilePath,\n\t\t};\n\t}\n\n\t// Parse YAML\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = parseYaml(content);\n\t} catch (err) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: `Invalid YAML syntax in ${filePath}`,\n\t\t\tdetails: [err instanceof Error ? err.message : String(err)],\n\t\t\tfilePath,\n\t\t};\n\t}\n\n\t// Validate against schema\n\tconst result = EntityDefinitionSchema.safeParse(parsed);\n\tif (!result.success) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: `Validation failed for ${filePath}`,\n\t\t\tdetails: formatZodErrors(result.error),\n\t\t\tfilePath,\n\t\t};\n\t}\n\n\treturn {\n\t\tsuccess: true,\n\t\tdefinition: result.data,\n\t\tfilePath,\n\t};\n}\n\n/**\n * Format Zod errors into human-readable messages\n */\nfunction formatZodErrors(error: ZodError): string[] {\n\treturn error.errors.map((err) => {\n\t\tconst path = err.path.join('.');\n\t\tconst location = path ? `at '${path}'` : 'at root';\n\t\treturn `${err.message} ${location}`;\n\t});\n}\n\n/**\n * Pretty-print a load error for CLI output\n */\nexport function formatLoadError(result: LoadError): string {\n\tconst lines = [`❌ ${result.error}`];\n\tif (result.details && result.details.length > 0) {\n\t\tlines.push('');\n\t\tfor (const detail of result.details) {\n\t\t\tlines.push(` • ${detail}`);\n\t\t}\n\t}\n\treturn lines.join('\\n');\n}\n\n/**\n * Load multiple entity files\n */\nexport function loadEntitiesFromYaml(filePaths: string[]): {\n\tsuccesses: LoadResult[];\n\tfailures: LoadError[];\n} {\n\tconst successes: LoadResult[] = [];\n\tconst failures: LoadError[] = [];\n\n\tfor (const filePath of filePaths) {\n\t\tconst result = loadEntityFromYaml(filePath);\n\t\tif (result.success) {\n\t\t\tsuccesses.push(result);\n\t\t} else {\n\t\t\tfailures.push(result);\n\t\t}\n\t}\n\n\treturn { successes, failures };\n}\n\n// ============================================================================\n// Relationship YAML Loading\n// ============================================================================\n\nexport interface RelationshipLoadResult {\n\tsuccess: true;\n\tdefinition: RelationshipDefinition;\n\tfilePath: string;\n}\n\nexport interface RelationshipLoadError {\n\tsuccess: false;\n\terror: string;\n\tdetails?: string[];\n\tfilePath: string;\n}\n\nexport type LoadRelationshipResult =\n\t| RelationshipLoadResult\n\t| RelationshipLoadError;\n\n/**\n * Load and validate a relationship definition from a YAML file\n */\nexport function loadRelationshipFromYaml(\n\tfilePath: string,\n): LoadRelationshipResult {\n\tif (!existsSync(filePath)) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: `File not found: ${filePath}`,\n\t\t\tfilePath,\n\t\t};\n\t}\n\n\tlet content: string;\n\ttry {\n\t\tcontent = readFileSync(filePath, 'utf-8');\n\t} catch (err) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: `Failed to read file: ${filePath}`,\n\t\t\tdetails: [err instanceof Error ? err.message : String(err)],\n\t\t\tfilePath,\n\t\t};\n\t}\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = parseYaml(content);\n\t} catch (err) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: `Invalid YAML syntax in ${filePath}`,\n\t\t\tdetails: [err instanceof Error ? err.message : String(err)],\n\t\t\tfilePath,\n\t\t};\n\t}\n\n\tconst result = RelationshipDefinitionSchema.safeParse(parsed);\n\tif (!result.success) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: `Validation failed for ${filePath}`,\n\t\t\tdetails: formatZodErrors(result.error),\n\t\t\tfilePath,\n\t\t};\n\t}\n\n\treturn {\n\t\tsuccess: true,\n\t\tdefinition: result.data,\n\t\tfilePath,\n\t};\n}\n\n/**\n * Load multiple relationship files\n */\nexport function loadRelationshipsFromYaml(filePaths: string[]): {\n\tsuccesses: RelationshipLoadResult[];\n\tfailures: RelationshipLoadError[];\n} {\n\tconst successes: RelationshipLoadResult[] = [];\n\tconst failures: RelationshipLoadError[] = [];\n\n\tfor (const filePath of filePaths) {\n\t\tconst result = loadRelationshipFromYaml(filePath);\n\t\tif (result.success) {\n\t\t\tsuccesses.push(result);\n\t\t} else {\n\t\t\tfailures.push(result);\n\t\t}\n\t}\n\n\treturn { successes, failures };\n}\n\n/**\n * Detect whether a YAML file is an entity or relationship definition.\n * Checks for the top-level discriminator key.\n */\nexport function detectYamlType(\n\tfilePath: string,\n): 'entity' | 'relationship' | 'unknown' {\n\tif (!existsSync(filePath)) return 'unknown';\n\n\ttry {\n\t\tconst content = readFileSync(filePath, 'utf-8');\n\t\tconst parsed = parseYaml(content) as Record<string, unknown>;\n\t\tif (parsed && typeof parsed === 'object') {\n\t\t\tif ('entity' in parsed) return 'entity';\n\t\t\tif ('relationship' in parsed) return 'relationship';\n\t\t}\n\t} catch {\n\t\t// Fall through\n\t}\n\treturn 'unknown';\n}\n","/**\n * Entity Loader\n *\n * Loads and parses all YAML entity files from a directory.\n * Reuses existing yaml-loader and entity-definition schema from codegen.\n */\n\nimport { readdirSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport type { EntityFamily } from '../analyzer/types.js';\nimport {\n\tloadEntityFromYaml,\n\tloadRelationshipFromYaml,\n\ttype LoadResult,\n\ttype LoadError,\n\ttype RelationshipLoadResult,\n\ttype RelationshipLoadError,\n} from '../utils/yaml-loader';\nimport type {\n\tParsedEntity,\n\tParsedEvent,\n\tParsedField,\n\tParsedProviderSync,\n\tParsedQuery,\n\tParsedRelationship,\n\tParsedRelationshipDefinition,\n\tParsedSync,\n\tParsedTypeDirection,\n\tAnalysisIssue,\n} from '../analyzer/types';\nimport {\n\tderiveRelationshipFKColumns,\n\tderiveTableName,\n\tderiveUniqueConstraint,\n\tcollectTypeNames,\n\ttype RelationshipDefinition,\n\ttype RelationshipTypes,\n} from '../schema/relationship-definition.schema';\n\nexport interface LoadEntitiesResult {\n\tentities: ParsedEntity[];\n\tissues: AnalysisIssue[];\n}\n\n/**\n * Transform a loaded entity definition into a ParsedEntity\n */\nfunction transformToEntity(result: LoadResult): ParsedEntity {\n\tconst { definition, filePath } = result;\n\n\tconst queries: ParsedQuery[] | undefined = definition.queries?.map((q) => ({\n\t\tby: q.by,\n\t\tunique: q.unique,\n\t\tselect: q.select,\n\t\torder: q.order,\n\t\tlimit: q.limit,\n\t\tvia: q.via,\n\t}));\n\n\tconst entity: ParsedEntity = {\n\t\tname: definition.entity.name,\n\t\tplural: definition.entity.plural,\n\t\ttable: definition.entity.table,\n\t\tfamily: definition.entity.family as EntityFamily | undefined,\n\t\tfolderStructure: definition.entity.folder_structure ?? 'nested',\n\t\tfields: new Map(),\n\t\trelationships: new Map(),\n\t\tbehaviors: definition.behaviors.map((b) => (typeof b === 'string' ? b : b.name)),\n\t\tqueries,\n\t\tsourcePath: filePath,\n\t};\n\n\t// Parse fields\n\tfor (const [name, fieldDef] of Object.entries(definition.fields)) {\n\t\tconst field: ParsedField = {\n\t\t\tname,\n\t\t\ttype: fieldDef.type,\n\t\t\trequired: fieldDef.required ?? false,\n\t\t\tnullable: fieldDef.nullable ?? false,\n\t\t\tunique: fieldDef.unique ?? false,\n\t\t\tindex: fieldDef.index ?? false,\n\t\t\tforeignKey: fieldDef.foreign_key ? parseForeignKey(fieldDef.foreign_key) : undefined,\n\t\t\tchoices: fieldDef.choices,\n\t\t\tconstraints: {\n\t\t\t\tminLength: fieldDef.min_length,\n\t\t\t\tmaxLength: fieldDef.max_length,\n\t\t\t\tmin: fieldDef.min,\n\t\t\t\tmax: fieldDef.max,\n\t\t\t},\n\t\t\tui: {\n\t\t\t\tlabel: fieldDef.ui_label,\n\t\t\t\ttype: fieldDef.ui_type,\n\t\t\t\timportance: fieldDef.ui_importance,\n\t\t\t\tgroup: fieldDef.ui_group,\n\t\t\t\tsortable: fieldDef.ui_sortable,\n\t\t\t\tfilterable: fieldDef.ui_filterable,\n\t\t\t\tvisible: fieldDef.ui_visible,\n\t\t\t},\n\t\t};\n\t\tentity.fields.set(name, field);\n\t}\n\n\t// Parse relationships\n\tif (definition.relationships) {\n\t\tfor (const [name, relDef] of Object.entries(definition.relationships)) {\n\t\t\tconst relationship: ParsedRelationship = {\n\t\t\t\tname,\n\t\t\t\ttype: relDef.type,\n\t\t\t\ttarget: relDef.target,\n\t\t\t\tforeignKey: relDef.foreign_key,\n\t\t\t\tinverse: relDef.inverse,\n\t\t\t\tthrough: relDef.through,\n\t\t\t\tresolved: false,\n\t\t\t};\n\t\t\tentity.relationships.set(name, relationship);\n\t\t}\n\t}\n\n\t// Parse sync configuration\n\tif (definition.sync) {\n\t\tconst syncDef = definition.sync;\n\t\tconst parsedSync: ParsedSync = {\n\t\t\telectric: syncDef.electric ?? false,\n\t\t};\n\n\t\tif (syncDef.providers) {\n\t\t\tparsedSync.providers = {};\n\t\t\tfor (const [providerName, providerDef] of Object.entries(syncDef.providers)) {\n\t\t\t\tconst parsedProvider: ParsedProviderSync = {\n\t\t\t\t\tremoteEntity: providerDef.remote_entity,\n\t\t\t\t\tdirection: providerDef.direction,\n\t\t\t\t\tcdc: providerDef.cdc ?? false,\n\t\t\t\t};\n\t\t\t\tif (providerDef.field_mapping) {\n\t\t\t\t\tparsedProvider.fieldMapping = providerDef.field_mapping;\n\t\t\t\t}\n\t\t\t\tif (providerDef.read_only_fields) {\n\t\t\t\t\tparsedProvider.readOnlyFields = providerDef.read_only_fields;\n\t\t\t\t}\n\t\t\t\tparsedSync.providers[providerName] = parsedProvider;\n\t\t\t}\n\t\t}\n\n\t\tentity.sync = parsedSync;\n\t}\n\n\t// Parse events\n\tif (definition.events) {\n\t\tentity.events = definition.events.map((ev): ParsedEvent => ({\n\t\t\tname: ev.name,\n\t\t\tqueue: ev.queue,\n\t\t\tbody: ev.body,\n\t\t\tgenerateHandler: ev.generate_handler,\n\t\t}));\n\t}\n\n\treturn entity;\n}\n\n/**\n * Parse a foreign key string (e.g., \"accounts.id\") into table and column\n */\nfunction parseForeignKey(fk: string): { table: string; column: string } {\n\tconst [table, column] = fk.split('.');\n\treturn { table, column: column ?? 'id' };\n}\n\n/**\n * Convert a load error to an analysis issue\n */\nfunction loadErrorToIssue(error: LoadError): AnalysisIssue[] {\n\tconst issues: AnalysisIssue[] = [];\n\n\tissues.push({\n\t\tseverity: 'error',\n\t\ttype: 'parse_error',\n\t\tmessage: error.error,\n\t\tpath: error.filePath,\n\t});\n\n\tif (error.details) {\n\t\tfor (const detail of error.details) {\n\t\t\tissues.push({\n\t\t\t\tseverity: 'error',\n\t\t\t\ttype: 'schema_error',\n\t\t\t\tmessage: detail,\n\t\t\t\tpath: error.filePath,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn issues;\n}\n\n/**\n * Load all entity YAML files from a directory\n */\nexport function loadEntities(entitiesDir: string): LoadEntitiesResult {\n\tconst entities: ParsedEntity[] = [];\n\tconst issues: AnalysisIssue[] = [];\n\n\tconst resolvedDir = resolve(entitiesDir);\n\n\t// Get all YAML files\n\tlet files: string[];\n\ttry {\n\t\tfiles = readdirSync(resolvedDir)\n\t\t\t.filter((f) => f.endsWith('.yaml') || f.endsWith('.yml'))\n\t\t\t.map((f) => join(resolvedDir, f));\n\t} catch (err) {\n\t\tissues.push({\n\t\t\tseverity: 'error',\n\t\t\ttype: 'parse_error',\n\t\t\tmessage: `Failed to read directory: ${resolvedDir}`,\n\t\t\tpath: resolvedDir,\n\t\t});\n\t\treturn { entities, issues };\n\t}\n\n\tif (files.length === 0) {\n\t\tissues.push({\n\t\t\tseverity: 'warning',\n\t\t\ttype: 'no_files',\n\t\t\tmessage: `No YAML files found in directory: ${resolvedDir}`,\n\t\t\tpath: resolvedDir,\n\t\t});\n\t\treturn { entities, issues };\n\t}\n\n\t// Load each file\n\tfor (const filePath of files) {\n\t\tconst result = loadEntityFromYaml(filePath);\n\n\t\tif (result.success) {\n\t\t\tentities.push(transformToEntity(result));\n\t\t} else {\n\t\t\tissues.push(...loadErrorToIssue(result));\n\t\t}\n\t}\n\n\treturn { entities, issues };\n}\n\n/**\n * Resolve cross-entity references\n */\nexport function resolveReferences(entities: ParsedEntity[]): AnalysisIssue[] {\n\tconst issues: AnalysisIssue[] = [];\n\tconst entityMap = new Map<string, ParsedEntity>();\n\n\t// Build entity map by name\n\tfor (const entity of entities) {\n\t\tif (entityMap.has(entity.name)) {\n\t\t\tissues.push({\n\t\t\t\tseverity: 'error',\n\t\t\t\ttype: 'duplicate_entity',\n\t\t\t\tentity: entity.name,\n\t\t\t\tmessage: `Duplicate entity name: ${entity.name}`,\n\t\t\t\tpath: entity.sourcePath,\n\t\t\t});\n\t\t}\n\t\tentityMap.set(entity.name, entity);\n\t}\n\n\t// Resolve relationships\n\tfor (const entity of entities) {\n\t\tfor (const [relName, rel] of entity.relationships) {\n\t\t\tconst targetEntity = entityMap.get(rel.target);\n\t\t\tif (targetEntity) {\n\t\t\t\trel.resolved = true;\n\t\t\t} else {\n\t\t\t\tissues.push({\n\t\t\t\t\tseverity: 'error',\n\t\t\t\t\ttype: 'missing_target',\n\t\t\t\t\tentity: entity.name,\n\t\t\t\t\tfield: relName,\n\t\t\t\t\tmessage: `Relationship '${relName}' references unknown entity '${rel.target}'`,\n\t\t\t\t\tpath: entity.sourcePath,\n\t\t\t\t\tsuggestion: `Define entity '${rel.target}' or fix the target name`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Check foreign key references\n\t\tfor (const [fieldName, field] of entity.fields) {\n\t\t\tif (field.foreignKey) {\n\t\t\t\tconst targetTable = field.foreignKey.table;\n\t\t\t\tconst targetEntity = Array.from(entityMap.values()).find(\n\t\t\t\t\t(e) => e.table === targetTable\n\t\t\t\t);\n\t\t\t\tif (!targetEntity) {\n\t\t\t\t\tissues.push({\n\t\t\t\t\t\tseverity: 'warning',\n\t\t\t\t\t\ttype: 'missing_fk_target',\n\t\t\t\t\t\tentity: entity.name,\n\t\t\t\t\t\tfield: fieldName,\n\t\t\t\t\t\tmessage: `Foreign key references unknown table '${targetTable}'`,\n\t\t\t\t\t\tpath: entity.sourcePath,\n\t\t\t\t\t\tsuggestion: `Define entity with table '${targetTable}' or fix the foreign_key reference`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn issues;\n}\n\n// ============================================================================\n// Relationship Loading\n// ============================================================================\n\nexport interface LoadRelationshipsResult {\n\trelationships: ParsedRelationshipDefinition[];\n\tissues: AnalysisIssue[];\n}\n\n/**\n * Transform a loaded relationship definition into a ParsedRelationshipDefinition.\n *\n * This resolves all auto-generated fields: FK columns, type directions,\n * temporal/sourced fields, unique constraints.\n */\nfunction transformToRelationshipDefinition(\n\tresult: RelationshipLoadResult,\n): ParsedRelationshipDefinition {\n\tconst { definition, filePath } = result;\n\tconst config = definition.relationship;\n\n\tconst { fromColumn, toColumn } = deriveRelationshipFKColumns(config);\n\tconst table = deriveTableName(config);\n\tconst uniqueOn = deriveUniqueConstraint(config);\n\n\t// Resolve type directions\n\tconst types = resolveTypeDirections(config.types);\n\n\t// Parse custom fields\n\tconst fields = new Map<string, ParsedField>();\n\tif (definition.fields) {\n\t\tfor (const [name, fieldDef] of Object.entries(definition.fields)) {\n\t\t\tconst field: ParsedField = {\n\t\t\t\tname,\n\t\t\t\ttype: fieldDef.type,\n\t\t\t\trequired: fieldDef.required ?? false,\n\t\t\t\tnullable: fieldDef.nullable ?? false,\n\t\t\t\tunique: fieldDef.unique ?? false,\n\t\t\t\tindex: fieldDef.index ?? false,\n\t\t\t\tforeignKey: fieldDef.foreign_key\n\t\t\t\t\t? parseForeignKey(fieldDef.foreign_key)\n\t\t\t\t\t: undefined,\n\t\t\t\tchoices: fieldDef.choices,\n\t\t\t\tconstraints: {\n\t\t\t\t\tminLength: fieldDef.min_length,\n\t\t\t\t\tmaxLength: fieldDef.max_length,\n\t\t\t\t\tmin: fieldDef.min,\n\t\t\t\t\tmax: fieldDef.max,\n\t\t\t\t},\n\t\t\t\tui: {\n\t\t\t\t\tlabel: fieldDef.ui_label,\n\t\t\t\t\ttype: fieldDef.ui_type,\n\t\t\t\t\timportance: fieldDef.ui_importance,\n\t\t\t\t\tgroup: fieldDef.ui_group,\n\t\t\t\t\tsortable: fieldDef.ui_sortable,\n\t\t\t\t\tfilterable: fieldDef.ui_filterable,\n\t\t\t\t\tvisible: fieldDef.ui_visible,\n\t\t\t\t},\n\t\t\t};\n\t\t\tfields.set(name, field);\n\t\t}\n\t}\n\n\t// Parse queries\n\tconst queries: ParsedQuery[] | undefined = definition.queries?.map((q) => ({\n\t\tby: q.by,\n\t\tunique: q.unique,\n\t\tselect: q.select,\n\t\torder: q.order,\n\t\tlimit: q.limit,\n\t}));\n\n\treturn {\n\t\tname: config.name,\n\t\ttable,\n\t\tfrom: config.from,\n\t\tto: config.to,\n\t\tselfReferential: config.from === config.to,\n\t\tfromColumn,\n\t\ttoColumn,\n\t\ttypes,\n\t\thasTypes: types.length > 0,\n\t\ttemporal: config.temporal,\n\t\tsourced: config.sourced,\n\t\tonDeleteFrom: config.on_delete_from ?? 'restrict',\n\t\tonDeleteTo: config.on_delete_to ?? 'restrict',\n\t\tuniqueOn,\n\t\tfields,\n\t\tqueries,\n\t\tsourcePath: filePath,\n\t};\n}\n\n/**\n * Resolve type directions from the YAML types: block.\n *\n * Simple list → all directed, no inverses.\n * Object map → each type has explicit direction metadata.\n */\nfunction resolveTypeDirections(\n\ttypes: RelationshipTypes | undefined,\n): ParsedTypeDirection[] {\n\tif (!types) return [];\n\n\tif (Array.isArray(types)) {\n\t\t// Simple list: all directed from→to\n\t\treturn types.map((name) => ({\n\t\t\tname,\n\t\t\tbidirectional: false,\n\t\t\tdirected: true,\n\t\t}));\n\t}\n\n\t// Object map: resolve each type's direction\n\treturn Object.entries(types).map(([name, dir]) => {\n\t\tconst direction = dir as { inverse?: string; bidirectional?: boolean; directed?: boolean };\n\t\treturn {\n\t\t\tname,\n\t\t\tinverse: direction.inverse,\n\t\t\tbidirectional: direction.bidirectional ?? false,\n\t\t\tdirected: direction.directed ?? (!direction.bidirectional && !direction.inverse),\n\t\t};\n\t});\n}\n\n/**\n * Load all relationship YAML files from a directory\n */\nexport function loadRelationships(\n\trelationshipsDir: string,\n): LoadRelationshipsResult {\n\tconst relationships: ParsedRelationshipDefinition[] = [];\n\tconst issues: AnalysisIssue[] = [];\n\n\tconst resolvedDir = resolve(relationshipsDir);\n\n\tlet files: string[];\n\ttry {\n\t\tfiles = readdirSync(resolvedDir)\n\t\t\t.filter((f) => f.endsWith('.yaml') || f.endsWith('.yml'))\n\t\t\t.map((f) => join(resolvedDir, f));\n\t} catch {\n\t\t// Directory doesn't exist — not an error, relationships are optional\n\t\treturn { relationships, issues };\n\t}\n\n\tif (files.length === 0) {\n\t\treturn { relationships, issues };\n\t}\n\n\tfor (const filePath of files) {\n\t\tconst result = loadRelationshipFromYaml(filePath);\n\n\t\tif (result.success) {\n\t\t\trelationships.push(transformToRelationshipDefinition(result));\n\t\t} else {\n\t\t\tissues.push(...loadErrorToIssue(result as unknown as LoadError));\n\t\t}\n\t}\n\n\treturn { relationships, issues };\n}\n\n/**\n * Resolve cross-references between relationship definitions and entities.\n * Validates that from/to entities exist.\n */\nexport function resolveRelationshipReferences(\n\trelationshipDefs: ParsedRelationshipDefinition[],\n\tentities: ParsedEntity[],\n): AnalysisIssue[] {\n\tconst issues: AnalysisIssue[] = [];\n\tconst entityNames = new Set(entities.map((e) => e.name));\n\n\tfor (const relDef of relationshipDefs) {\n\t\tif (!entityNames.has(relDef.from)) {\n\t\t\tissues.push({\n\t\t\t\tseverity: 'warning',\n\t\t\t\ttype: 'missing_relationship_endpoint',\n\t\t\t\tentity: relDef.name,\n\t\t\t\tmessage: `Relationship '${relDef.name}' references unknown 'from' entity '${relDef.from}'`,\n\t\t\t\tpath: relDef.sourcePath,\n\t\t\t\tsuggestion: `Define entity '${relDef.from}' or fix the 'from' value`,\n\t\t\t});\n\t\t}\n\n\t\tif (!entityNames.has(relDef.to)) {\n\t\t\tissues.push({\n\t\t\t\tseverity: 'warning',\n\t\t\t\ttype: 'missing_relationship_endpoint',\n\t\t\t\tentity: relDef.name,\n\t\t\t\tmessage: `Relationship '${relDef.name}' references unknown 'to' entity '${relDef.to}'`,\n\t\t\t\tpath: relDef.sourcePath,\n\t\t\t\tsuggestion: `Define entity '${relDef.to}' or fix the 'to' value`,\n\t\t\t});\n\t\t}\n\n\t\t// Check for duplicate relationship names\n\t\tconst dupes = relationshipDefs.filter((r) => r.name === relDef.name);\n\t\tif (dupes.length > 1) {\n\t\t\tissues.push({\n\t\t\t\tseverity: 'error',\n\t\t\t\ttype: 'duplicate_relationship',\n\t\t\t\tentity: relDef.name,\n\t\t\t\tmessage: `Duplicate relationship name: ${relDef.name}`,\n\t\t\t\tpath: relDef.sourcePath,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn issues;\n}\n\nexport { loadEntityFromYaml } from '../utils/yaml-loader';\nexport { loadRelationshipFromYaml } from '../utils/yaml-loader';\n","/**\n * Parser Module\n *\n * Exports entity and relationship loading and parsing utilities.\n */\n\nexport {\n\tloadEntities,\n\tloadRelationships,\n\tresolveReferences,\n\tresolveRelationshipReferences,\n\tloadEntityFromYaml,\n\tloadRelationshipFromYaml,\n\ttype LoadEntitiesResult,\n\ttype LoadRelationshipsResult,\n} from './load-entities';\n","/**\n * Graph Builder\n *\n * Builds a domain graph from parsed entities, including nodes and edges.\n * Tracks bidirectional connections between entities.\n */\n\nimport type {\n\tParsedEntity,\n\tParsedRelationship,\n\tParsedRelationshipDefinition,\n\tDomainGraph,\n\tRelationshipEdge,\n\tEntityNode,\n} from './types';\n\n/**\n * Infer cardinality from relationship type\n */\nfunction inferCardinality(type: string): '1:1' | '1:N' | 'N:1' | 'N:M' {\n\tswitch (type) {\n\t\tcase 'belongs_to':\n\t\t\treturn 'N:1';\n\t\tcase 'has_many':\n\t\t\treturn '1:N';\n\t\tcase 'has_one':\n\t\t\treturn '1:1';\n\t\tdefault:\n\t\t\treturn '1:N';\n\t}\n}\n\n/**\n * Check if an edge already exists in the opposite direction\n */\nfunction hasReverseEdge(\n\tedges: RelationshipEdge[],\n\tfrom: string,\n\tto: string\n): RelationshipEdge | undefined {\n\treturn edges.find((e) => e.from === to && e.to === from);\n}\n\n/**\n * Build a domain graph from parsed entities\n */\nexport function buildDomainGraph(\n\tentities: ParsedEntity[],\n\trelationshipDefinitions: ParsedRelationshipDefinition[] = [],\n): DomainGraph {\n\tconst entityMap = new Map<string, ParsedEntity>();\n\tconst relDefMap = new Map<string, ParsedRelationshipDefinition>();\n\tconst edges: RelationshipEdge[] = [];\n\n\t// Build entity map\n\tfor (const entity of entities) {\n\t\tentityMap.set(entity.name, entity);\n\t}\n\n\t// Build relationship definition map\n\tfor (const relDef of relationshipDefinitions) {\n\t\trelDefMap.set(relDef.name, relDef);\n\t}\n\n\t// Build edges from inline entity relationships (belongs_to, has_many, has_one)\n\tfor (const entity of entities) {\n\t\tfor (const [relName, rel] of entity.relationships) {\n\t\t\tif (!rel.resolved) continue;\n\n\t\t\t// Check if reverse edge already exists\n\t\t\tconst reverseEdge = hasReverseEdge(edges, entity.name, rel.target);\n\n\t\t\tconst edge: RelationshipEdge = {\n\t\t\t\tfrom: entity.name,\n\t\t\t\tto: rel.target,\n\t\t\t\trelationship: rel,\n\t\t\t\tcardinality: inferCardinality(rel.type),\n\t\t\t\tbidirectional: reverseEdge !== undefined,\n\t\t\t};\n\n\t\t\t// Mark reverse edge as bidirectional too\n\t\t\tif (reverseEdge) {\n\t\t\t\treverseEdge.bidirectional = true;\n\t\t\t}\n\n\t\t\tedges.push(edge);\n\t\t}\n\t}\n\n\t// Build edges from first-class relationship definitions (junction entities)\n\tfor (const relDef of relationshipDefinitions) {\n\t\tconst fromExists = entityMap.has(relDef.from);\n\t\tconst toExists = entityMap.has(relDef.to);\n\n\t\tif (fromExists && toExists) {\n\t\t\t// Create an N:M edge — junction tables are always many-to-many\n\t\t\tconst edge: RelationshipEdge = {\n\t\t\t\tfrom: relDef.from,\n\t\t\t\tto: relDef.to,\n\t\t\t\trelationship: {\n\t\t\t\t\tname: relDef.name,\n\t\t\t\t\ttype: 'has_many',\n\t\t\t\t\ttarget: relDef.to,\n\t\t\t\t\tforeignKey: relDef.fromColumn,\n\t\t\t\t\tresolved: true,\n\t\t\t\t},\n\t\t\t\tcardinality: 'N:M',\n\t\t\t\tbidirectional: relDef.types.some((t) => t.bidirectional),\n\t\t\t};\n\n\t\t\tedges.push(edge);\n\t\t}\n\t}\n\n\treturn { entities: entityMap, relationshipDefinitions: relDefMap, edges };\n}\n\n/**\n * Get all entities related to a given entity within a specified depth\n */\nexport function getRelatedEntities(\n\tgraph: DomainGraph,\n\tentityName: string,\n\tdepth = 1\n): Set<string> {\n\tconst related = new Set<string>();\n\tconst visited = new Set<string>();\n\tconst queue: Array<{ name: string; currentDepth: number }> = [\n\t\t{ name: entityName, currentDepth: 0 },\n\t];\n\n\twhile (queue.length > 0) {\n\t\tconst item = queue.shift();\n\t\tif (!item) continue;\n\n\t\tconst { name, currentDepth } = item;\n\t\tif (visited.has(name) || currentDepth > depth) continue;\n\t\tvisited.add(name);\n\n\t\tfor (const edge of graph.edges) {\n\t\t\tif (edge.from === name && !visited.has(edge.to)) {\n\t\t\t\trelated.add(edge.to);\n\t\t\t\tqueue.push({ name: edge.to, currentDepth: currentDepth + 1 });\n\t\t\t}\n\t\t\tif (edge.to === name && !visited.has(edge.from)) {\n\t\t\t\trelated.add(edge.from);\n\t\t\t\tqueue.push({ name: edge.from, currentDepth: currentDepth + 1 });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn related;\n}\n\n/**\n * Find entities with no relationships (orphans)\n */\nexport function findOrphanEntities(graph: DomainGraph): string[] {\n\tconst orphans: string[] = [];\n\tfor (const [name] of graph.entities) {\n\t\tconst hasRelationship = graph.edges.some((e) => e.from === name || e.to === name);\n\t\tif (!hasRelationship) {\n\t\t\torphans.push(name);\n\t\t}\n\t}\n\treturn orphans;\n}\n\n/**\n * Find circular dependencies in the graph\n */\nexport function findCircularDependencies(graph: DomainGraph): string[][] {\n\tconst cycles: string[][] = [];\n\tconst visited = new Set<string>();\n\tconst recursionStack = new Set<string>();\n\n\tfunction dfs(node: string, path: string[]): void {\n\t\tvisited.add(node);\n\t\trecursionStack.add(node);\n\n\t\tconst outgoingEdges = graph.edges.filter((e) => e.from === node);\n\t\tfor (const edge of outgoingEdges) {\n\t\t\tif (!visited.has(edge.to)) {\n\t\t\t\tdfs(edge.to, [...path, edge.to]);\n\t\t\t} else if (recursionStack.has(edge.to)) {\n\t\t\t\t// Found cycle\n\t\t\t\tconst cycleStart = path.indexOf(edge.to);\n\t\t\t\tif (cycleStart !== -1) {\n\t\t\t\t\tcycles.push([...path.slice(cycleStart), edge.to]);\n\t\t\t\t} else {\n\t\t\t\t\t// The cycle starts at edge.to which is in the recursion stack\n\t\t\t\t\tcycles.push([...path, edge.to]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\trecursionStack.delete(node);\n\t}\n\n\tfor (const [name] of graph.entities) {\n\t\tif (!visited.has(name)) {\n\t\t\tdfs(name, [name]);\n\t\t}\n\t}\n\n\t// Deduplicate cycles (same cycle can be detected from different starting points)\n\tconst uniqueCycles: string[][] = [];\n\tconst seen = new Set<string>();\n\n\tfor (const cycle of cycles) {\n\t\t// Normalize cycle by rotating to start with smallest element\n\t\tconst minIndex = cycle.indexOf(\n\t\t\tcycle.reduce((min, val) => (val < min ? val : min), cycle[0])\n\t\t);\n\t\tconst normalized = [...cycle.slice(minIndex), ...cycle.slice(0, minIndex)];\n\t\tconst key = normalized.join('->');\n\n\t\tif (!seen.has(key)) {\n\t\t\tseen.add(key);\n\t\t\tuniqueCycles.push(cycle);\n\t\t}\n\t}\n\n\treturn uniqueCycles;\n}\n\n/**\n * Build entity nodes for visualization\n */\nexport function buildEntityNodes(graph: DomainGraph): EntityNode[] {\n\tconst nodes: EntityNode[] = [];\n\tfor (const [name, entity] of graph.entities) {\n\t\tnodes.push({\n\t\t\tid: name,\n\t\t\tname: entity.name,\n\t\t\tentity,\n\t\t});\n\t}\n\treturn nodes;\n}\n","/**\n * External ID Tracking Behavior\n *\n * Adds external_id, provider, and provider_metadata fields to track\n * records that are synced from external systems (e.g., Salesforce, HubSpot).\n */\n\nimport type { BehaviorDefinition } from './types';\n\nexport const externalIdTrackingBehavior: BehaviorDefinition = {\n\tname: 'external_id_tracking',\n\tdescription: 'Adds external_id, provider, and provider_metadata fields for external system sync tracking',\n\n\tfields: [\n\t\t{\n\t\t\tname: 'external_id',\n\t\t\tcamelName: 'externalId',\n\t\t\ttype: 'string',\n\t\t\ttsType: 'string | null',\n\t\t\tdrizzleType: 'varchar',\n\t\t\tdrizzleImports: ['varchar', 'index'],\n\t\t\tzodType: 'z.string().nullable()',\n\t\t\tnullable: true,\n\t\t\tui: {\n\t\t\t\tlabel: 'External ID',\n\t\t\t\ttype: 'text',\n\t\t\t\timportance: 'tertiary',\n\t\t\t\tgroup: 'metadata',\n\t\t\t\tvisible: false,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: 'provider',\n\t\t\tcamelName: 'provider',\n\t\t\ttype: 'string',\n\t\t\ttsType: 'string | null',\n\t\t\tdrizzleType: 'varchar',\n\t\t\tdrizzleImports: ['varchar'],\n\t\t\tzodType: 'z.string().nullable()',\n\t\t\tnullable: true,\n\t\t\tui: {\n\t\t\t\tlabel: 'Provider',\n\t\t\t\ttype: 'text',\n\t\t\t\timportance: 'tertiary',\n\t\t\t\tgroup: 'metadata',\n\t\t\t\tvisible: false,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: 'provider_metadata',\n\t\t\tcamelName: 'providerMetadata',\n\t\t\ttype: 'json',\n\t\t\ttsType: 'unknown | null',\n\t\t\tdrizzleType: 'jsonb',\n\t\t\tdrizzleImports: ['jsonb'],\n\t\t\tzodType: 'z.unknown().nullable()',\n\t\t\tnullable: true,\n\t\t\tui: {\n\t\t\t\tlabel: 'Provider Metadata',\n\t\t\t\ttype: 'json',\n\t\t\t\timportance: 'tertiary',\n\t\t\t\tgroup: 'metadata',\n\t\t\t\tvisible: false,\n\t\t\t},\n\t\t},\n\t],\n\n\tdrizzleImports: ['varchar', 'jsonb', 'index'],\n\n\tconfigKey: 'externalIdTracking',\n};\n","/**\n * Soft Delete Behavior\n *\n * Adds deleted_at field for soft delete functionality.\n * Records are marked as deleted instead of being removed from the database.\n * BaseRepository automatically filters soft-deleted records in queries.\n */\n\nimport type { BehaviorDefinition } from './types';\n\nexport const softDeleteBehavior: BehaviorDefinition = {\n\tname: 'soft_delete',\n\tdescription: 'Adds deleted_at field for soft delete functionality',\n\n\tfields: [\n\t\t{\n\t\t\tname: 'deleted_at',\n\t\t\tcamelName: 'deletedAt',\n\t\t\ttype: 'datetime',\n\t\t\ttsType: 'Date | null',\n\t\t\tdrizzleType: 'timestamp',\n\t\t\tdrizzleImports: ['timestamp'],\n\t\t\tzodType: 'z.coerce.date().nullable()',\n\t\t\tnullable: true,\n\t\t\tui: {\n\t\t\t\tlabel: 'Deleted At',\n\t\t\t\ttype: 'datetime',\n\t\t\t\timportance: 'tertiary',\n\t\t\t\tgroup: 'metadata',\n\t\t\t\tvisible: false,\n\t\t\t},\n\t\t},\n\t],\n\n\tdrizzleImports: ['timestamp'],\n\n\tmethods: [\n\t\t'softDelete',\n\t\t'restore',\n\t\t'findWithDeleted',\n\t\t'findOnlyDeleted',\n\t\t'baseQuery', // Modified to filter deleted records\n\t],\n\n\tconfigKey: 'softDelete',\n};\n","/**\n * Timestamps Behavior\n *\n * Adds created_at and updated_at fields to track entity lifecycle.\n * These fields are automatically managed by BaseRepository.\n */\n\nimport type { BehaviorDefinition } from './types';\n\nexport const timestampsBehavior: BehaviorDefinition = {\n\tname: 'timestamps',\n\tdescription: 'Adds created_at and updated_at timestamp fields',\n\n\tfields: [\n\t\t{\n\t\t\tname: 'created_at',\n\t\t\tcamelName: 'createdAt',\n\t\t\ttype: 'datetime',\n\t\t\ttsType: 'Date',\n\t\t\tdrizzleType: 'timestamp',\n\t\t\tdrizzleImports: ['timestamp'],\n\t\t\tzodType: 'z.coerce.date()',\n\t\t\tnullable: false,\n\t\t\tdefault: 'now()',\n\t\t\tui: {\n\t\t\t\tlabel: 'Created At',\n\t\t\t\ttype: 'datetime',\n\t\t\t\timportance: 'tertiary',\n\t\t\t\tgroup: 'metadata',\n\t\t\t\tvisible: false,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: 'updated_at',\n\t\t\tcamelName: 'updatedAt',\n\t\t\ttype: 'datetime',\n\t\t\ttsType: 'Date',\n\t\t\tdrizzleType: 'timestamp',\n\t\t\tdrizzleImports: ['timestamp'],\n\t\t\tzodType: 'z.coerce.date()',\n\t\t\tnullable: false,\n\t\t\tdefault: 'now()',\n\t\t\tui: {\n\t\t\t\tlabel: 'Updated At',\n\t\t\t\ttype: 'datetime',\n\t\t\t\timportance: 'tertiary',\n\t\t\t\tgroup: 'metadata',\n\t\t\t\tvisible: false,\n\t\t\t},\n\t\t},\n\t],\n\n\tdrizzleImports: ['timestamp'],\n\n\tmethods: ['applyTimestampsOnCreate', 'applyTimestampsOnUpdate'],\n\n\tconfigKey: 'timestamps',\n};\n","/**\n * User Tracking Behavior\n *\n * Adds created_by and updated_by fields to track which user\n * created and last modified an entity.\n * These fields are automatically managed by BaseRepository when\n * a RepositoryContext with userId is provided.\n */\n\nimport type { BehaviorDefinition } from './types';\n\nexport const userTrackingBehavior: BehaviorDefinition = {\n\tname: 'user_tracking',\n\tdescription: 'Adds created_by and updated_by user reference fields',\n\n\tfields: [\n\t\t{\n\t\t\tname: 'created_by',\n\t\t\tcamelName: 'createdBy',\n\t\t\ttype: 'uuid',\n\t\t\ttsType: 'string | null',\n\t\t\tdrizzleType: 'uuid',\n\t\t\tdrizzleImports: ['uuid'],\n\t\t\tzodType: 'z.string().uuid().nullable()',\n\t\t\tnullable: true,\n\t\t\tforeignKey: 'users.id',\n\t\t\tui: {\n\t\t\t\tlabel: 'Created By',\n\t\t\t\ttype: 'reference',\n\t\t\t\timportance: 'tertiary',\n\t\t\t\tgroup: 'metadata',\n\t\t\t\tvisible: false,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: 'updated_by',\n\t\t\tcamelName: 'updatedBy',\n\t\t\ttype: 'uuid',\n\t\t\ttsType: 'string | null',\n\t\t\tdrizzleType: 'uuid',\n\t\t\tdrizzleImports: ['uuid'],\n\t\t\tzodType: 'z.string().uuid().nullable()',\n\t\t\tnullable: true,\n\t\t\tforeignKey: 'users.id',\n\t\t\tui: {\n\t\t\t\tlabel: 'Updated By',\n\t\t\t\ttype: 'reference',\n\t\t\t\timportance: 'tertiary',\n\t\t\t\tgroup: 'metadata',\n\t\t\t\tvisible: false,\n\t\t\t},\n\t\t},\n\t],\n\n\tdrizzleImports: ['uuid'],\n\n\tmethods: ['applyUserTrackingOnCreate', 'applyUserTrackingOnUpdate'],\n\n\tconfigKey: 'userTracking',\n};\n","/**\n * Behavior Registry - Central registry for all entity behaviors\n *\n * Provides functions to:\n * - Get behavior definitions by name\n * - Validate behavior configurations\n * - Resolve fields added by behaviors\n */\n\nimport { externalIdTrackingBehavior } from './external-id-tracking';\nimport { softDeleteBehavior } from './soft-delete';\nimport { timestampsBehavior } from './timestamps';\nimport type {\n\tBehaviorConfig,\n\tBehaviorDefinition,\n\tBehaviorField,\n\tNormalizedBehaviorConfig,\n\tResolvedBehaviors,\n\tValidationResult,\n} from './types';\nimport { userTrackingBehavior } from './user-tracking';\n\n// ============================================================================\n// Behavior Registry\n// ============================================================================\n\nconst behaviorRegistry = new Map<string, BehaviorDefinition>([\n\t['timestamps', timestampsBehavior],\n\t['soft_delete', softDeleteBehavior],\n\t['user_tracking', userTrackingBehavior],\n\t['external_id_tracking', externalIdTrackingBehavior],\n]);\n\n/**\n * Get a behavior definition by name\n */\nexport function getBehavior(name: string): BehaviorDefinition | undefined {\n\treturn behaviorRegistry.get(name);\n}\n\n/**\n * Get all registered behavior names\n */\nexport function getAllBehaviorNames(): string[] {\n\treturn Array.from(behaviorRegistry.keys());\n}\n\n// ============================================================================\n// Config Normalization\n// ============================================================================\n\n/**\n * Normalize a behavior config to always have name and options\n */\nexport function normalizeBehaviorConfig(\n\tconfig: BehaviorConfig,\n): NormalizedBehaviorConfig {\n\tif (typeof config === 'string') {\n\t\treturn { name: config, options: {} };\n\t}\n\treturn { name: config.name, options: config.options ?? {} };\n}\n\n/**\n * Normalize an array of behavior configs\n */\nexport function normalizeBehaviorConfigs(\n\tconfigs: BehaviorConfig[],\n): NormalizedBehaviorConfig[] {\n\treturn configs.map(normalizeBehaviorConfig);\n}\n\n// ============================================================================\n// Validation\n// ============================================================================\n\n/**\n * Validate a set of behavior configurations\n * Checks for unknown behaviors, missing dependencies, and conflicts\n */\nexport function validateBehaviors(configs: BehaviorConfig[]): ValidationResult {\n\tconst errors: string[] = [];\n\tconst warnings: string[] = [];\n\tconst normalized = normalizeBehaviorConfigs(configs);\n\tconst enabledNames = new Set(normalized.map((c) => c.name));\n\n\tfor (const config of normalized) {\n\t\tconst behavior = getBehavior(config.name);\n\n\t\t// Check behavior exists\n\t\tif (!behavior) {\n\t\t\terrors.push(`Unknown behavior: '${config.name}'`);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Check dependencies\n\t\tif (behavior.requires) {\n\t\t\tfor (const req of behavior.requires) {\n\t\t\t\tif (!enabledNames.has(req)) {\n\t\t\t\t\terrors.push(\n\t\t\t\t\t\t`Behavior '${config.name}' requires '${req}' which is not enabled`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Check conflicts\n\t\tif (behavior.conflicts) {\n\t\t\tfor (const conflict of behavior.conflicts) {\n\t\t\t\tif (enabledNames.has(conflict)) {\n\t\t\t\t\terrors.push(\n\t\t\t\t\t\t`Behavior '${config.name}' conflicts with '${conflict}'`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tvalid: errors.length === 0,\n\t\terrors,\n\t\twarnings,\n\t};\n}\n\n// ============================================================================\n// Field Resolution\n// ============================================================================\n\n/**\n * Get all fields added by a set of behaviors\n */\nexport function resolveBehaviorFields(\n\tconfigs: BehaviorConfig[],\n): BehaviorField[] {\n\tconst normalized = normalizeBehaviorConfigs(configs);\n\tconst fields: BehaviorField[] = [];\n\tconst addedFieldNames = new Set<string>();\n\n\tfor (const config of normalized) {\n\t\tconst behavior = getBehavior(config.name);\n\t\tif (!behavior) continue;\n\n\t\tfor (const field of behavior.fields) {\n\t\t\t// Avoid duplicate fields if multiple behaviors add the same field\n\t\t\tif (!addedFieldNames.has(field.name)) {\n\t\t\t\tfields.push(field);\n\t\t\t\taddedFieldNames.add(field.name);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fields;\n}\n\n/**\n * Get all Drizzle imports needed by a set of behaviors\n */\nexport function resolveBehaviorDrizzleImports(\n\tconfigs: BehaviorConfig[],\n): string[] {\n\tconst normalized = normalizeBehaviorConfigs(configs);\n\tconst imports = new Set<string>();\n\n\tfor (const config of normalized) {\n\t\tconst behavior = getBehavior(config.name);\n\t\tif (!behavior) continue;\n\n\t\tfor (const imp of behavior.drizzleImports) {\n\t\t\timports.add(imp);\n\t\t}\n\t}\n\n\treturn Array.from(imports).sort();\n}\n\n// ============================================================================\n// Full Resolution\n// ============================================================================\n\n/**\n * Resolve all behavior data for templates\n */\nexport function resolveBehaviors(configs: BehaviorConfig[]): ResolvedBehaviors {\n\tconst normalized = normalizeBehaviorConfigs(configs);\n\tconst fields = resolveBehaviorFields(configs);\n\tconst drizzleImports = resolveBehaviorDrizzleImports(configs);\n\n\tconst enabledNames = new Set(normalized.map((c) => c.name));\n\n\tconst hasTimestamps = enabledNames.has('timestamps');\n\tconst hasSoftDelete = enabledNames.has('soft_delete');\n\tconst hasUserTracking = enabledNames.has('user_tracking');\n\tconst hasExternalIdTracking = enabledNames.has('external_id_tracking');\n\n\treturn {\n\t\tconfigs: normalized,\n\t\tfields,\n\t\tdrizzleImports,\n\t\trepositoryConfig: {\n\t\t\ttimestamps: hasTimestamps,\n\t\t\tsoftDelete: hasSoftDelete,\n\t\t\tuserTracking: hasUserTracking,\n\t\t\tversionable: false, // Future behavior\n\t\t},\n\t\thasBehaviors: normalized.length > 0,\n\t\thasTimestamps,\n\t\thasSoftDelete,\n\t\thasUserTracking,\n\t\thasExternalIdTracking,\n\t};\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport type {\n\tBehaviorConfig,\n\tBehaviorDefinition,\n\tBehaviorField,\n\tNormalizedBehaviorConfig,\n\tResolvedBehaviors,\n\tValidationResult,\n} from './types';\n\nexport { timestampsBehavior } from './timestamps';\nexport { softDeleteBehavior } from './soft-delete';\nexport { userTrackingBehavior } from './user-tracking';\nexport { externalIdTrackingBehavior } from './external-id-tracking';\n","/**\n * Consistency Checker\n *\n * Performs various consistency checks on the domain model:\n * - Missing relationship targets\n * - Missing inverse relationships\n * - Missing indexes on filterable fields\n * - Orphan entities (no relationships)\n * - Circular dependencies\n * - Naming conventions\n * - Missing UI metadata\n */\n\nimport type { ParsedEntity, DomainGraph, AnalysisIssue } from './types';\nimport { findOrphanEntities, findCircularDependencies } from './graph-builder';\nimport { resolveBehaviorFields } from '../behaviors/index';\n\n/**\n * Run all consistency checks on the domain graph\n */\nexport function checkConsistency(graph: DomainGraph): AnalysisIssue[] {\n\tconst issues: AnalysisIssue[] = [];\n\n\t// Check each entity\n\tfor (const [name, entity] of graph.entities) {\n\t\tissues.push(...checkEntityConsistency(entity));\n\t\tissues.push(...checkRelationshipConsistency(entity, graph));\n\t\tissues.push(...checkNamingConventions(entity));\n\t\tissues.push(...checkMissingIndexes(entity));\n\t\tissues.push(...checkUiMetadata(entity));\n\t\tif (entity.queries !== undefined) {\n\t\t\tissues.push(...checkQueryFieldReferences(entity));\n\t\t}\n\t\tif (entity.sync !== undefined) {\n\t\t\tissues.push(...checkSyncFieldMappingReferences(entity));\n\t\t\tissues.push(...checkExternalIdTrackingCollision(entity));\n\t\t}\n\t}\n\n\t// Check graph-level issues\n\tissues.push(...checkOrphanEntities(graph));\n\tissues.push(...checkCircularReferences(graph));\n\tissues.push(...checkMissingInverses(graph));\n\n\treturn issues;\n}\n\n/**\n * Check entity-level consistency\n */\nfunction checkEntityConsistency(entity: ParsedEntity): AnalysisIssue[] {\n\tconst issues: AnalysisIssue[] = [];\n\n\t// Check for missing primary key\n\tif (!entity.fields.has('id')) {\n\t\tissues.push({\n\t\t\tseverity: 'info',\n\t\t\ttype: 'missing_id',\n\t\t\tentity: entity.name,\n\t\t\tmessage: 'Entity missing standard \"id\" field',\n\t\t\tsuggestion: 'Add an \"id\" field with type \"uuid\"',\n\t\t});\n\t}\n\n\t// Check for missing timestamps\n\tconst hasCreatedAt = entity.fields.has('created_at');\n\tconst hasTimestampsBehavior = entity.behaviors.includes('timestamps');\n\n\tif (!hasCreatedAt && !hasTimestampsBehavior) {\n\t\tissues.push({\n\t\t\tseverity: 'info',\n\t\t\ttype: 'missing_timestamps',\n\t\t\tentity: entity.name,\n\t\t\tmessage: 'Entity missing \"created_at\" field and \"timestamps\" behavior',\n\t\t\tsuggestion: 'Add \"timestamps\" to behaviors or add created_at/updated_at fields',\n\t\t});\n\t}\n\n\treturn issues;\n}\n\n/**\n * Check relationship consistency\n */\nfunction checkRelationshipConsistency(\n\tentity: ParsedEntity,\n\tgraph: DomainGraph\n): AnalysisIssue[] {\n\tconst issues: AnalysisIssue[] = [];\n\n\tfor (const [relName, rel] of entity.relationships) {\n\t\t// Check for belongs_to without matching foreign key field\n\t\tif (rel.type === 'belongs_to') {\n\t\t\tconst fkField = entity.fields.get(rel.foreignKey);\n\t\t\tif (!fkField) {\n\t\t\t\tissues.push({\n\t\t\t\t\tseverity: 'warning',\n\t\t\t\t\ttype: 'missing_fk_field',\n\t\t\t\t\tentity: entity.name,\n\t\t\t\t\tfield: relName,\n\t\t\t\t\tmessage: `Relationship \"${relName}\" references foreign key \"${rel.foreignKey}\" but field doesn't exist`,\n\t\t\t\t\tsuggestion: `Add field \"${rel.foreignKey}\" with foreign_key reference`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Check for has_many relationships - target should have the FK field\n\t\tif (rel.type === 'has_many' || rel.type === 'has_one') {\n\t\t\tconst targetEntity = graph.entities.get(rel.target);\n\t\t\tif (targetEntity) {\n\t\t\t\tconst targetFkField = targetEntity.fields.get(rel.foreignKey);\n\t\t\t\tif (!targetFkField) {\n\t\t\t\t\tissues.push({\n\t\t\t\t\t\tseverity: 'warning',\n\t\t\t\t\t\ttype: 'missing_target_fk',\n\t\t\t\t\t\tentity: entity.name,\n\t\t\t\t\t\tfield: relName,\n\t\t\t\t\t\tmessage: `Relationship \"${relName}\" expects foreign key \"${rel.foreignKey}\" on \"${rel.target}\" but field doesn't exist`,\n\t\t\t\t\t\tsuggestion: `Add field \"${rel.foreignKey}\" to \"${rel.target}\" entity`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn issues;\n}\n\n/**\n * Check naming conventions\n */\nfunction checkNamingConventions(entity: ParsedEntity): AnalysisIssue[] {\n\tconst issues: AnalysisIssue[] = [];\n\n\t// Entity name should be lowercase snake_case\n\tif (entity.name !== entity.name.toLowerCase()) {\n\t\tissues.push({\n\t\t\tseverity: 'warning',\n\t\t\ttype: 'naming_convention',\n\t\t\tentity: entity.name,\n\t\t\tmessage: 'Entity name should be lowercase',\n\t\t\tsuggestion: `Use \"${entity.name.toLowerCase()}\"`,\n\t\t});\n\t}\n\n\t// Check field naming\n\tfor (const [fieldName] of entity.fields) {\n\t\tif (fieldName !== fieldName.toLowerCase()) {\n\t\t\tissues.push({\n\t\t\t\tseverity: 'warning',\n\t\t\t\ttype: 'naming_convention',\n\t\t\t\tentity: entity.name,\n\t\t\t\tfield: fieldName,\n\t\t\t\tmessage: 'Field name should be snake_case',\n\t\t\t\tsuggestion: `Use \"${toSnakeCase(fieldName)}\"`,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Check relationship naming\n\tfor (const [relName] of entity.relationships) {\n\t\tif (relName !== relName.toLowerCase()) {\n\t\t\tissues.push({\n\t\t\t\tseverity: 'warning',\n\t\t\t\ttype: 'naming_convention',\n\t\t\t\tentity: entity.name,\n\t\t\t\tfield: relName,\n\t\t\t\tmessage: 'Relationship name should be snake_case',\n\t\t\t\tsuggestion: `Use \"${toSnakeCase(relName)}\"`,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn issues;\n}\n\n/**\n * Check for missing indexes on filterable fields\n */\nfunction checkMissingIndexes(entity: ParsedEntity): AnalysisIssue[] {\n\tconst issues: AnalysisIssue[] = [];\n\n\tfor (const [fieldName, field] of entity.fields) {\n\t\t// Check if field is marked as filterable but has no index\n\t\tif (field.ui.filterable && !field.index && !field.unique) {\n\t\t\tissues.push({\n\t\t\t\tseverity: 'warning',\n\t\t\t\ttype: 'missing_index',\n\t\t\t\tentity: entity.name,\n\t\t\t\tfield: fieldName,\n\t\t\t\tmessage: `Field \"${fieldName}\" is filterable but has no index`,\n\t\t\t\tsuggestion: 'Add \"index: true\" to improve query performance',\n\t\t\t});\n\t\t}\n\n\t\t// Foreign key fields should typically have an index\n\t\tif (field.foreignKey && !field.index && !field.unique) {\n\t\t\tissues.push({\n\t\t\t\tseverity: 'info',\n\t\t\t\ttype: 'missing_fk_index',\n\t\t\t\tentity: entity.name,\n\t\t\t\tfield: fieldName,\n\t\t\t\tmessage: `Foreign key field \"${fieldName}\" has no index`,\n\t\t\t\tsuggestion: 'Add \"index: true\" for better join performance',\n\t\t\t});\n\t\t}\n\t}\n\n\treturn issues;\n}\n\n/**\n * Check for missing UI metadata\n */\nfunction checkUiMetadata(entity: ParsedEntity): AnalysisIssue[] {\n\tconst issues: AnalysisIssue[] = [];\n\n\t// System fields that don't need UI metadata\n\tconst systemFields = new Set(['id', 'created_at', 'updated_at', 'deleted_at', 'tenant_id']);\n\n\tfor (const [fieldName, field] of entity.fields) {\n\t\tif (systemFields.has(fieldName)) continue;\n\n\t\tconst hasAnyUiMeta =\n\t\t\tfield.ui.label !== undefined ||\n\t\t\tfield.ui.type !== undefined ||\n\t\t\tfield.ui.group !== undefined;\n\n\t\tif (!hasAnyUiMeta) {\n\t\t\tissues.push({\n\t\t\t\tseverity: 'info',\n\t\t\t\ttype: 'missing_ui_metadata',\n\t\t\t\tentity: entity.name,\n\t\t\t\tfield: fieldName,\n\t\t\t\tmessage: `Field \"${fieldName}\" has no UI metadata`,\n\t\t\t\tsuggestion: 'Add ui_label, ui_type, ui_group for better admin panel display',\n\t\t\t});\n\t\t}\n\t}\n\n\treturn issues;\n}\n\n/**\n * Check for orphan entities\n */\nfunction checkOrphanEntities(graph: DomainGraph): AnalysisIssue[] {\n\tconst orphans = findOrphanEntities(graph);\n\treturn orphans.map((name) => ({\n\t\tseverity: 'info' as const,\n\t\ttype: 'orphan_entity',\n\t\tentity: name,\n\t\tmessage: `Entity \"${name}\" has no relationships to other entities`,\n\t\tsuggestion: 'Consider if this entity should be related to others',\n\t}));\n}\n\n/**\n * Check for circular references\n */\nfunction checkCircularReferences(graph: DomainGraph): AnalysisIssue[] {\n\tconst cycles = findCircularDependencies(graph);\n\treturn cycles.map((cycle) => ({\n\t\tseverity: 'info' as const,\n\t\ttype: 'circular_dependency',\n\t\tentity: cycle[0],\n\t\tmessage: `Circular reference detected: ${cycle.join(' -> ')}`,\n\t\tsuggestion: 'Verify this is intentional (e.g., self-referential hierarchy)',\n\t}));\n}\n\n/**\n * Check for missing inverse relationships\n */\nfunction checkMissingInverses(graph: DomainGraph): AnalysisIssue[] {\n\tconst issues: AnalysisIssue[] = [];\n\n\tfor (const edge of graph.edges) {\n\t\tconst { from, to, relationship } = edge;\n\t\tconst targetEntity = graph.entities.get(to);\n\t\tif (!targetEntity) continue;\n\n\t\t// Check if target has an inverse relationship back to source\n\t\tconst hasInverse = Array.from(targetEntity.relationships.values()).some(\n\t\t\t(rel) => rel.target === from\n\t\t);\n\n\t\t// belongs_to relationships typically don't need explicit inverses\n\t\t// (the has_many on the other side serves as the inverse)\n\t\tif (!hasInverse && relationship.type !== 'belongs_to') {\n\t\t\tissues.push({\n\t\t\t\tseverity: 'info',\n\t\t\t\ttype: 'missing_inverse',\n\t\t\t\tentity: from,\n\t\t\t\tfield: relationship.name,\n\t\t\t\tmessage: `Relationship \"${relationship.name}\" to \"${to}\" has no inverse defined on target`,\n\t\t\t\tsuggestion: `Add inverse relationship on \"${to}\" pointing back to \"${from}\"`,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn issues;\n}\n\n/**\n * Get the set of all valid field names for an entity, including behavior-added fields\n * and belongs_to foreign key fields (which the template emits as columns even when\n * not explicitly declared under `fields:`).\n */\nfunction getAvailableFieldNames(entity: ParsedEntity): string[] {\n\tconst entityFieldNames = Array.from(entity.fields.keys());\n\tconst behaviorFields = resolveBehaviorFields(entity.behaviors);\n\tconst behaviorFieldNames = behaviorFields.map((f) => f.name);\n\tconst belongsToFkNames: string[] = [];\n\tfor (const rel of entity.relationships.values()) {\n\t\tif (rel.type === 'belongs_to' && rel.foreignKey) {\n\t\t\tbelongsToFkNames.push(rel.foreignKey);\n\t\t}\n\t}\n\treturn [...new Set([...entityFieldNames, ...behaviorFieldNames, ...belongsToFkNames])];\n}\n\n/**\n * Check that query.by and query.select fields reference existing entity fields\n */\nfunction checkQueryFieldReferences(entity: ParsedEntity): AnalysisIssue[] {\n\tconst issues: AnalysisIssue[] = [];\n\tconst availableFields = getAvailableFieldNames(entity);\n\tconst availableSet = new Set(availableFields);\n\n\tfor (const query of entity.queries ?? []) {\n\t\t// Skip by-field validation when via is specified — those fields come from the junction table\n\t\tif (!query.via) {\n\t\t\tfor (const fieldName of query.by) {\n\t\t\t\tif (!availableSet.has(fieldName)) {\n\t\t\t\t\tissues.push({\n\t\t\t\t\t\tseverity: 'error',\n\t\t\t\t\t\ttype: 'unknown_query_field',\n\t\t\t\t\t\tentity: entity.name,\n\t\t\t\t\t\tfield: fieldName,\n\t\t\t\t\t\tmessage: `Query references unknown field \"${fieldName}\" in entity \"${entity.name}\". Available fields: ${availableFields.join(', ')}`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const fieldName of query.select ?? []) {\n\t\t\tif (!availableSet.has(fieldName)) {\n\t\t\t\tissues.push({\n\t\t\t\t\tseverity: 'error',\n\t\t\t\t\ttype: 'unknown_query_field',\n\t\t\t\t\tentity: entity.name,\n\t\t\t\t\tfield: fieldName,\n\t\t\t\t\tmessage: `Query references unknown field \"${fieldName}\" in entity \"${entity.name}\". Available fields: ${availableFields.join(', ')}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn issues;\n}\n\n/**\n * Check that sync field_mapping keys and read_only_fields reference existing entity fields\n */\nfunction checkSyncFieldMappingReferences(entity: ParsedEntity): AnalysisIssue[] {\n\tconst issues: AnalysisIssue[] = [];\n\tconst availableFields = getAvailableFieldNames(entity);\n\tconst availableSet = new Set(availableFields);\n\n\tfor (const [providerName, provider] of Object.entries(entity.sync?.providers ?? {})) {\n\t\tfor (const fieldName of Object.keys(provider.fieldMapping ?? {})) {\n\t\t\tif (!availableSet.has(fieldName)) {\n\t\t\t\tissues.push({\n\t\t\t\t\tseverity: 'warning',\n\t\t\t\t\ttype: 'unknown_sync_field_mapping',\n\t\t\t\t\tentity: entity.name,\n\t\t\t\t\tfield: fieldName,\n\t\t\t\t\tmessage: `Sync field mapping references unknown field \"${fieldName}\" for provider \"${providerName}\" in entity \"${entity.name}\"`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tfor (const fieldName of provider.readOnlyFields ?? []) {\n\t\t\tif (!availableSet.has(fieldName)) {\n\t\t\t\tissues.push({\n\t\t\t\t\tseverity: 'warning',\n\t\t\t\t\ttype: 'unknown_sync_field_mapping',\n\t\t\t\t\tentity: entity.name,\n\t\t\t\t\tfield: fieldName,\n\t\t\t\t\tmessage: `Sync field mapping references unknown field \"${fieldName}\" for provider \"${providerName}\" in entity \"${entity.name}\"`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn issues;\n}\n\n/**\n * Check for potential collision between external_id_tracking behavior and sync field_mapping\n */\nfunction checkExternalIdTrackingCollision(entity: ParsedEntity): AnalysisIssue[] {\n\tconst issues: AnalysisIssue[] = [];\n\n\tconst hasExternalIdTracking = entity.behaviors.includes('external_id_tracking');\n\tif (!hasExternalIdTracking) return issues;\n\n\tfor (const [providerName, provider] of Object.entries(entity.sync?.providers ?? {})) {\n\t\tif (provider.fieldMapping && 'external_id' in provider.fieldMapping) {\n\t\t\tissues.push({\n\t\t\t\tseverity: 'warning',\n\t\t\t\ttype: 'external_id_tracking_collision',\n\t\t\t\tentity: entity.name,\n\t\t\t\tfield: 'external_id',\n\t\t\t\tmessage: `Entity \"${entity.name}\" has external_id_tracking behavior and also maps \"external_id\" in sync field_mapping for provider \"${providerName}\". The behavior-added field may collide with the mapped field.`,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn issues;\n}\n\n/**\n * Convert string to snake_case\n */\nfunction toSnakeCase(str: string): string {\n\treturn str\n\t\t.replace(/([A-Z])/g, '_$1')\n\t\t.toLowerCase()\n\t\t.replace(/^_/, '');\n}\n","/**\n * Statistics\n *\n * Computes statistics about the domain model:\n * - Entity counts\n * - Field counts and type distribution\n * - Relationship counts and type distribution\n */\n\nimport type { ParsedEntity, DomainGraph, DomainStatistics } from './types';\n\n/**\n * Compute domain statistics from the graph\n */\nexport function computeStatistics(graph: DomainGraph): DomainStatistics {\n\tconst entities = Array.from(graph.entities.values());\n\n\tconst fieldsByType: Record<string, number> = {};\n\tconst relationshipsByType: Record<string, number> = {};\n\tlet totalFields = 0;\n\tlet totalRelationships = 0;\n\tlet entitiesWithBehaviors = 0;\n\n\tfor (const entity of entities) {\n\t\ttotalFields += entity.fields.size;\n\t\ttotalRelationships += entity.relationships.size;\n\n\t\tif (entity.behaviors.length > 0) {\n\t\t\tentitiesWithBehaviors++;\n\t\t}\n\n\t\t// Count fields by type\n\t\tfor (const field of entity.fields.values()) {\n\t\t\tfieldsByType[field.type] = (fieldsByType[field.type] ?? 0) + 1;\n\t\t}\n\n\t\t// Count relationships by type\n\t\tfor (const rel of entity.relationships.values()) {\n\t\t\trelationshipsByType[rel.type] = (relationshipsByType[rel.type] ?? 0) + 1;\n\t\t}\n\t}\n\n\treturn {\n\t\ttotalEntities: entities.length,\n\t\ttotalFields,\n\t\ttotalRelationships,\n\t\tfieldsByType,\n\t\trelationshipsByType,\n\t\tentitiesWithBehaviors,\n\t\taverageFieldsPerEntity: entities.length > 0 ? totalFields / entities.length : 0,\n\t};\n}\n\n/**\n * Get a breakdown of field properties\n */\nexport function getFieldBreakdown(graph: DomainGraph): {\n\trequired: number;\n\tnullable: number;\n\tindexed: number;\n\tunique: number;\n\twithForeignKey: number;\n\twithConstraints: number;\n} {\n\tlet required = 0;\n\tlet nullable = 0;\n\tlet indexed = 0;\n\tlet unique = 0;\n\tlet withForeignKey = 0;\n\tlet withConstraints = 0;\n\n\tfor (const entity of graph.entities.values()) {\n\t\tfor (const field of entity.fields.values()) {\n\t\t\tif (field.required) required++;\n\t\t\tif (field.nullable) nullable++;\n\t\t\tif (field.index) indexed++;\n\t\t\tif (field.unique) unique++;\n\t\t\tif (field.foreignKey) withForeignKey++;\n\n\t\t\tconst hasConstraints =\n\t\t\t\tfield.constraints.minLength !== undefined ||\n\t\t\t\tfield.constraints.maxLength !== undefined ||\n\t\t\t\tfield.constraints.min !== undefined ||\n\t\t\t\tfield.constraints.max !== undefined;\n\t\t\tif (hasConstraints) withConstraints++;\n\t\t}\n\t}\n\n\treturn { required, nullable, indexed, unique, withForeignKey, withConstraints };\n}\n\n/**\n * Get UI metadata coverage statistics\n */\nexport function getUiMetadataCoverage(graph: DomainGraph): {\n\twithLabel: number;\n\twithType: number;\n\twithGroup: number;\n\twithImportance: number;\n\ttotal: number;\n} {\n\tlet withLabel = 0;\n\tlet withType = 0;\n\tlet withGroup = 0;\n\tlet withImportance = 0;\n\tlet total = 0;\n\n\tfor (const entity of graph.entities.values()) {\n\t\tfor (const field of entity.fields.values()) {\n\t\t\ttotal++;\n\t\t\tif (field.ui.label) withLabel++;\n\t\t\tif (field.ui.type) withType++;\n\t\t\tif (field.ui.group) withGroup++;\n\t\t\tif (field.ui.importance) withImportance++;\n\t\t}\n\t}\n\n\treturn { withLabel, withType, withGroup, withImportance, total };\n}\n","/**\n * Transitive Relationship Suggester\n *\n * Detects potential transitive relationships in the domain graph.\n * Uses BFS to find 2-3 hop paths through has_many relationships and\n * generates ready-to-paste YAML snippets for the entity definition files.\n */\n\nimport type {\n\tDomainGraph,\n\tParsedEntity,\n\tParsedRelationship,\n\tTransitiveSuggestion,\n\tTransitivePath,\n\tPathHop,\n} from './types';\n\nexport interface SuggesterOptions {\n\tmaxDepth?: number;\n\texcludeEntities?: string[];\n\texcludePatterns?: RegExp[];\n}\n\nconst DEFAULT_OPTIONS: Required<SuggesterOptions> = {\n\tmaxDepth: 3,\n\texcludeEntities: ['workspace', 'tenant'],\n\texcludePatterns: [/_audit$/, /_log$/, /_history$/],\n};\n\ninterface BFSNode {\n\tentity: string;\n\tdepth: number;\n\tpath: PathHop[];\n\tvisited: Set<string>;\n}\n\n/**\n * Suggest transitive relationships based on graph analysis\n */\nexport function suggestTransitiveRelationships(\n\tgraph: DomainGraph,\n\toptions?: SuggesterOptions\n): TransitiveSuggestion[] {\n\tconst opts = { ...DEFAULT_OPTIONS, ...options };\n\tconst suggestions: TransitiveSuggestion[] = [];\n\n\t// Process each entity as a potential source\n\tfor (const [entityName, entity] of graph.entities) {\n\t\tif (shouldExcludeEntity(entityName, opts)) continue;\n\n\t\tconst paths = findTransitivePaths(graph, entityName, opts);\n\t\tfor (const path of paths) {\n\t\t\tsuggestions.push(createSuggestion(path));\n\t\t}\n\t}\n\n\treturn suggestions;\n}\n\n/**\n * Check if entity should be excluded from analysis\n */\nfunction shouldExcludeEntity(\n\tentityName: string,\n\topts: Required<SuggesterOptions>\n): boolean {\n\t// Check exclude list\n\tif (opts.excludeEntities.includes(entityName)) {\n\t\treturn true;\n\t}\n\n\t// Check exclude patterns\n\tfor (const pattern of opts.excludePatterns) {\n\t\tif (pattern.test(entityName)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Find all valid transitive paths from a source entity using BFS\n */\nfunction findTransitivePaths(\n\tgraph: DomainGraph,\n\tsourceEntity: string,\n\topts: Required<SuggesterOptions>\n): TransitivePath[] {\n\tconst paths: TransitivePath[] = [];\n\tconst sourceEntityData = graph.entities.get(sourceEntity);\n\tif (!sourceEntityData) return paths;\n\n\tconst queue: BFSNode[] = [\n\t\t{\n\t\t\tentity: sourceEntity,\n\t\t\tdepth: 0,\n\t\t\tpath: [],\n\t\t\tvisited: new Set([sourceEntity]),\n\t\t},\n\t];\n\n\twhile (queue.length > 0) {\n\t\tconst current = queue.shift();\n\t\tif (!current) continue;\n\n\t\tconst { entity, depth, path, visited } = current;\n\n\t\t// Don't go beyond max depth\n\t\tif (depth >= opts.maxDepth) continue;\n\n\t\tconst currentEntity = graph.entities.get(entity);\n\t\tif (!currentEntity) continue;\n\n\t\t// Explore has_many and has_one relationships\n\t\tfor (const [relName, rel] of currentEntity.relationships) {\n\t\t\t// Skip if already has a through defined\n\t\t\tif (rel.through) continue;\n\n\t\t\t// Only follow has_many and has_one relationships\n\t\t\tif (rel.type !== 'has_many' && rel.type !== 'has_one') continue;\n\n\t\t\tconst target = rel.target;\n\n\t\t\t// Skip excluded entities\n\t\t\tif (shouldExcludeEntity(target, opts)) continue;\n\n\t\t\t// Avoid cycles\n\t\t\tif (visited.has(target)) continue;\n\n\t\t\tconst newPath: PathHop[] = [\n\t\t\t\t...path,\n\t\t\t\t{\n\t\t\t\t\tvia: entity,\n\t\t\t\t\trelationship: relName,\n\t\t\t\t\tforeignKey: rel.foreignKey,\n\t\t\t\t},\n\t\t\t];\n\n\t\t\t// If we're at depth 2 or more, we have a valid transitive path\n\t\t\tif (depth >= 1) {\n\t\t\t\t// Check if a direct relationship already exists\n\t\t\t\tif (!hasDirectRelationship(sourceEntityData, target)) {\n\t\t\t\t\tconst transitivePath = buildTransitivePath(\n\t\t\t\t\t\tsourceEntity,\n\t\t\t\t\t\ttarget,\n\t\t\t\t\t\tnewPath\n\t\t\t\t\t);\n\t\t\t\t\tif (transitivePath) {\n\t\t\t\t\t\tpaths.push(transitivePath);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Continue searching deeper\n\t\t\tif (depth + 1 < opts.maxDepth) {\n\t\t\t\tqueue.push({\n\t\t\t\t\tentity: target,\n\t\t\t\t\tdepth: depth + 1,\n\t\t\t\t\tpath: newPath,\n\t\t\t\t\tvisited: new Set([...visited, target]),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn paths;\n}\n\n/**\n * Check if a direct relationship already exists between source and target\n */\nfunction hasDirectRelationship(\n\tsourceEntity: ParsedEntity,\n\ttargetName: string\n): boolean {\n\tfor (const rel of sourceEntity.relationships.values()) {\n\t\tif (rel.target === targetName && !rel.through) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\n/**\n * Build a TransitivePath from BFS result\n */\nfunction buildTransitivePath(\n\tsource: string,\n\ttarget: string,\n\thops: PathHop[]\n): TransitivePath | null {\n\tif (hops.length === 0) return null;\n\n\t// Build through path: \"relationships.nested_relationship\"\n\tconst throughPath = hops.map((hop) => hop.relationship).join('.');\n\n\t// Generate semantic name\n\tconst suggestedName = generateSemanticName(source, target, hops);\n\n\t// Generate YAML snippet\n\tconst yamlSnippet = generateYamlSnippet(suggestedName, target, throughPath);\n\n\treturn {\n\t\tsource,\n\t\ttarget,\n\t\thops,\n\t\tsuggestedName,\n\t\tthroughPath,\n\t\tyamlSnippet,\n\t};\n}\n\n/**\n * Generate a semantic relationship name\n * Examples:\n * - user -> meetings -> action_items = \"meeting_action_items\"\n * - user -> owned_opportunities -> updates = \"owned_opportunity_updates\"\n */\nfunction generateSemanticName(\n\tsource: string,\n\ttarget: string,\n\thops: PathHop[]\n): string {\n\t// Use the first hop relationship name as a prefix\n\tconst firstHop = hops[0].relationship;\n\n\t// For simple 2-hop paths, combine first relationship with target\n\tif (hops.length === 2) {\n\t\t// Handle pluralization\n\t\tconst prefix = firstHop.replace(/s$/, ''); // singular form\n\t\treturn `${prefix}_${target}`;\n\t}\n\n\t// For 3-hop paths, combine all meaningful parts\n\tconst parts = [firstHop.replace(/s$/, ''), target];\n\treturn parts.join('_');\n}\n\n/**\n * Generate ready-to-paste YAML snippet\n */\nfunction generateYamlSnippet(\n\tname: string,\n\ttarget: string,\n\tthroughPath: string\n): string {\n\treturn ` ${name}:\n type: has_many\n target: ${target}\n through: \"${throughPath}\"`;\n}\n\n/**\n * Create a TransitiveSuggestion from a TransitivePath\n */\nfunction createSuggestion(path: TransitivePath): TransitiveSuggestion {\n\tconst pathDescription = [path.source, ...path.hops.map((h) => h.via), path.target]\n\t\t.join(' -> ');\n\n\treturn {\n\t\tseverity: 'info',\n\t\ttype: 'transitive_suggestion',\n\t\tentity: path.source,\n\t\tmessage: `Potential transitive relationship: ${pathDescription}`,\n\t\tsuggestion: `Add \"${path.suggestedName}\" relationship via \"${path.throughPath}\"`,\n\t\tpath,\n\t};\n}\n","/**\n * Manifest Persistence\n *\n * Handles reading, writing, and staleness detection for the codegen manifest.\n * Uses SHA-256 hash of entity files for deterministic staleness checking.\n */\n\nimport { createHash } from 'crypto';\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync } from 'fs';\nimport { join } from 'path';\nimport type {\n\tCodegenManifest,\n\tAnalysisResult,\n\tTransitiveSuggestion,\n\tManifestEntity,\n\tManifestField,\n\tManifestRelationship,\n\tManifestSuggestion,\n\tParsedEntity,\n} from './types';\nimport { findOrphanEntities, findCircularDependencies } from './graph-builder';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nexport const MANIFEST_FILE = 'manifest.json';\nexport const MANIFEST_VERSION = 1;\n\n/**\n * Get the manifest directory name (configurable via env var)\n */\nexport function getManifestDir(): string {\n\treturn process.env.CODEGEN_MANIFEST_DIR || '.codegen';\n}\n\n// ============================================================================\n// Path Utilities\n// ============================================================================\n\n/**\n * Get manifest directory and file paths\n */\nexport function getManifestPaths(projectRoot: string): { dir: string; file: string } {\n\tconst dir = join(projectRoot, getManifestDir());\n\tconst file = join(dir, MANIFEST_FILE);\n\treturn { dir, file };\n}\n\n// ============================================================================\n// Hash Computation\n// ============================================================================\n\n/**\n * Compute SHA-256 hash of all YAML files in the entities directory.\n * Results are deterministic (sorted file order).\n */\nexport async function computeEntityFilesHash(entitiesDir: string): Promise<string> {\n\tif (!existsSync(entitiesDir)) {\n\t\treturn createHash('sha256').update('').digest('hex');\n\t}\n\n\t// Recursively gather all YAML files\n\tconst yamlFiles: string[] = [];\n\n\tfunction walkDir(dir: string): void {\n\t\tconst entries = readdirSync(dir);\n\t\tfor (const entry of entries) {\n\t\t\tconst fullPath = join(dir, entry);\n\t\t\tconst stat = statSync(fullPath);\n\t\t\tif (stat.isDirectory()) {\n\t\t\t\twalkDir(fullPath);\n\t\t\t} else if (stat.isFile() && (entry.endsWith('.yaml') || entry.endsWith('.yml'))) {\n\t\t\t\tyamlFiles.push(fullPath);\n\t\t\t}\n\t\t}\n\t}\n\n\twalkDir(entitiesDir);\n\n\t// Sort for deterministic hashing\n\tyamlFiles.sort();\n\n\t// Compute combined hash\n\tconst hash = createHash('sha256');\n\tfor (const file of yamlFiles) {\n\t\tconst content = readFileSync(file, 'utf-8');\n\t\thash.update(file); // Include file path for uniqueness\n\t\thash.update(content);\n\t}\n\n\treturn hash.digest('hex');\n}\n\n// ============================================================================\n// Manifest I/O\n// ============================================================================\n\n/**\n * Read manifest from disk.\n * Returns null if not found or version mismatch.\n */\nexport function readManifest(projectRoot: string): CodegenManifest | null {\n\tconst { file } = getManifestPaths(projectRoot);\n\n\tif (!existsSync(file)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst content = readFileSync(file, 'utf-8');\n\t\tconst manifest = JSON.parse(content) as CodegenManifest;\n\n\t\t// Version check\n\t\tif (manifest.version !== MANIFEST_VERSION) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn manifest;\n\t} catch (error) {\n\t\t// Invalid JSON or read error\n\t\treturn null;\n\t}\n}\n\n/**\n * Write manifest to disk.\n * Creates .codegen directory if needed.\n */\nexport function writeManifest(projectRoot: string, manifest: CodegenManifest): void {\n\tconst { dir, file } = getManifestPaths(projectRoot);\n\n\t// Ensure directory exists\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true });\n\t}\n\n\t// Write manifest with pretty formatting\n\tconst content = JSON.stringify(manifest, null, 2);\n\twriteFileSync(file, content, 'utf-8');\n}\n\n// ============================================================================\n// Staleness Detection\n// ============================================================================\n\n/**\n * Check if manifest is stale (entity files have changed).\n */\nexport async function isManifestStale(\n\tprojectRoot: string,\n\tentitiesDir: string\n): Promise<boolean> {\n\tconst manifest = readManifest(projectRoot);\n\n\tif (!manifest) {\n\t\treturn true; // No manifest = stale\n\t}\n\n\tconst currentHash = await computeEntityFilesHash(entitiesDir);\n\treturn manifest.entityFilesHash !== currentHash;\n}\n\n// ============================================================================\n// Manifest Building\n// ============================================================================\n\n/**\n * Convert ParsedEntity to ManifestEntity\n */\nfunction toManifestEntity(entity: ParsedEntity): ManifestEntity {\n\tconst fields: Record<string, ManifestField> = {};\n\tfor (const [name, field] of entity.fields) {\n\t\tfields[name] = {\n\t\t\tname: field.name,\n\t\t\ttype: field.type,\n\t\t\trequired: field.required,\n\t\t\tnullable: field.nullable,\n\t\t\tunique: field.unique,\n\t\t\tindex: field.index,\n\t\t\tforeignKey: field.foreignKey,\n\t\t\tchoices: field.choices,\n\t\t};\n\t}\n\n\tconst relationships: Record<string, ManifestRelationship> = {};\n\tfor (const [name, rel] of entity.relationships) {\n\t\trelationships[name] = {\n\t\t\ttype: rel.type,\n\t\t\ttarget: rel.target,\n\t\t\tforeignKey: rel.foreignKey,\n\t\t\tthrough: rel.through,\n\t\t\tinverse: rel.inverse,\n\t\t};\n\t}\n\n\treturn {\n\t\tsourcePath: entity.sourcePath,\n\t\ttable: entity.table,\n\t\tplural: entity.plural,\n\t\tfields,\n\t\trelationships,\n\t\tbehaviors: entity.behaviors,\n\t};\n}\n\n/**\n * Merge transitive suggestions with existing manifest suggestions.\n * Preserves status (pending/accepted/skipped) from existing manifest.\n */\nfunction mergeSuggestions(\n\tnewSuggestions: TransitiveSuggestion[],\n\texistingManifest?: CodegenManifest | null\n): ManifestSuggestion[] {\n\tconst now = new Date().toISOString();\n\tconst existingSuggestions = existingManifest?.suggestions.transitive || [];\n\tconst existingMap = new Map<string, ManifestSuggestion>();\n\n\t// Build map of existing suggestions by ID\n\tfor (const existing of existingSuggestions) {\n\t\texistingMap.set(existing.id, existing);\n\t}\n\n\t// Merge new suggestions\n\tconst merged: ManifestSuggestion[] = [];\n\n\tfor (const suggestion of newSuggestions) {\n\t\tconst id = `${suggestion.path.source}->${suggestion.path.target}`;\n\t\tconst existing = existingMap.get(id);\n\n\t\tif (existing) {\n\t\t\t// Preserve existing suggestion with updated content\n\t\t\tmerged.push({\n\t\t\t\tid,\n\t\t\t\tsource: suggestion.path.source,\n\t\t\t\ttarget: suggestion.path.target,\n\t\t\t\tthroughPath: suggestion.path.throughPath,\n\t\t\t\tsuggestedName: suggestion.path.suggestedName,\n\t\t\t\tyamlSnippet: suggestion.path.yamlSnippet,\n\t\t\t\tstatus: existing.status, // Preserve status\n\t\t\t\tdetectedAt: existing.detectedAt, // Preserve original detection time\n\t\t\t\tresolvedAt: existing.resolvedAt,\n\t\t\t});\n\t\t\texistingMap.delete(id); // Mark as processed\n\t\t} else {\n\t\t\t// New suggestion\n\t\t\tmerged.push({\n\t\t\t\tid,\n\t\t\t\tsource: suggestion.path.source,\n\t\t\t\ttarget: suggestion.path.target,\n\t\t\t\tthroughPath: suggestion.path.throughPath,\n\t\t\t\tsuggestedName: suggestion.path.suggestedName,\n\t\t\t\tyamlSnippet: suggestion.path.yamlSnippet,\n\t\t\t\tstatus: 'pending',\n\t\t\t\tdetectedAt: now,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Keep resolved suggestions from existing manifest (accepted/skipped)\n\tfor (const [id, existing] of existingMap) {\n\t\tif (existing.status !== 'pending') {\n\t\t\tmerged.push(existing);\n\t\t}\n\t\t// Pending suggestions that are no longer detected are dropped\n\t}\n\n\treturn merged;\n}\n\n/**\n * Build manifest from analysis result\n */\nexport async function buildManifest(\n\tanalysis: AnalysisResult,\n\ttransitiveSuggestions: TransitiveSuggestion[],\n\tentitiesDir: string,\n\texistingManifest?: CodegenManifest | null\n): Promise<CodegenManifest> {\n\tconst entities: Record<string, ManifestEntity> = {};\n\n\t// Convert entities\n\tfor (const entity of analysis.entities) {\n\t\tentities[entity.name] = toManifestEntity(entity);\n\t}\n\n\t// Build graph metadata\n\tconst orphans = findOrphanEntities(analysis.graph);\n\tconst cycles = findCircularDependencies(analysis.graph);\n\n\t// Merge suggestions (preserving existing status)\n\tconst mergedSuggestions = mergeSuggestions(transitiveSuggestions, existingManifest);\n\n\t// Compute entity files hash\n\tconst entityFilesHash = await computeEntityFilesHash(entitiesDir);\n\n\tconst manifest: CodegenManifest = {\n\t\tversion: MANIFEST_VERSION,\n\t\tgeneratedAt: new Date().toISOString(),\n\t\tentityFilesHash,\n\t\tentities,\n\t\tgraph: {\n\t\t\tedges: analysis.graph.edges.map((edge) => ({\n\t\t\t\tfrom: edge.from,\n\t\t\t\tto: edge.to,\n\t\t\t\trelationship: edge.relationship.name,\n\t\t\t\tcardinality: edge.cardinality === 'N:M' ? '1:N' : edge.cardinality,\n\t\t\t\tbidirectional: edge.bidirectional,\n\t\t\t})),\n\t\t\torphans,\n\t\t\tcycles,\n\t\t},\n\t\tsuggestions: {\n\t\t\ttransitive: mergedSuggestions,\n\t\t},\n\t\tstatistics: {\n\t\t\ttotalEntities: analysis.statistics.totalEntities,\n\t\t\ttotalFields: analysis.statistics.totalFields,\n\t\t\ttotalRelationships: analysis.statistics.totalRelationships,\n\t\t\ttransitivePathsDetected: transitiveSuggestions.length,\n\t\t},\n\t};\n\n\treturn manifest;\n}\n\n// ============================================================================\n// Suggestion Management\n// ============================================================================\n\n/**\n * Update status of a specific suggestion.\n * Returns true if updated, false if suggestion not found.\n */\nexport function updateSuggestionStatus(\n\tprojectRoot: string,\n\tsuggestionId: string,\n\tstatus: 'accepted' | 'skipped'\n): boolean {\n\tconst manifest = readManifest(projectRoot);\n\tif (!manifest) {\n\t\treturn false;\n\t}\n\n\tconst suggestion = manifest.suggestions.transitive.find((s) => s.id === suggestionId);\n\tif (!suggestion) {\n\t\treturn false;\n\t}\n\n\tsuggestion.status = status;\n\tsuggestion.resolvedAt = new Date().toISOString();\n\n\twriteManifest(projectRoot, manifest);\n\treturn true;\n}\n\n/**\n * Update status of all pending suggestions.\n * Returns count of updated suggestions.\n */\nexport function updateAllSuggestionStatus(\n\tprojectRoot: string,\n\tstatus: 'accepted' | 'skipped'\n): number {\n\tconst manifest = readManifest(projectRoot);\n\tif (!manifest) {\n\t\treturn 0;\n\t}\n\n\tlet count = 0;\n\tconst now = new Date().toISOString();\n\n\tfor (const suggestion of manifest.suggestions.transitive) {\n\t\tif (suggestion.status === 'pending') {\n\t\t\tsuggestion.status = status;\n\t\t\tsuggestion.resolvedAt = now;\n\t\t\tcount++;\n\t\t}\n\t}\n\n\tif (count > 0) {\n\t\twriteManifest(projectRoot, manifest);\n\t}\n\n\treturn count;\n}\n\n/**\n * Get all pending suggestions from manifest.\n */\nexport function getPendingSuggestions(projectRoot: string): ManifestSuggestion[] {\n\tconst manifest = readManifest(projectRoot);\n\tif (!manifest) {\n\t\treturn [];\n\t}\n\n\treturn manifest.suggestions.transitive.filter((s) => s.status === 'pending');\n}\n","/**\n * Serializes a DomainGraph to plain JSON (converts Maps to Records).\n *\n * Used by the CLI `codegen project graph` command to produce JSON\n * that the schema-graph-viewer can consume via its SchemaAdapter.\n */\nimport type {\n DomainGraph,\n ParsedEntity,\n ParsedField,\n ParsedRelationship,\n ParsedRelationshipDefinition,\n} from './types';\n\nexport interface SerializedDomainGraph {\n entities: Record<string, SerializedEntity>;\n relationshipDefinitions: Record<string, SerializedRelationshipDefinition>;\n edges: SerializedEdge[];\n}\n\nexport interface SerializedEntity {\n name: string;\n plural: string;\n table: string;\n family?: string;\n fields: Record<string, SerializedField>;\n relationships: Record<string, SerializedRelationship>;\n behaviors: string[];\n queries?: Array<{ by: string[]; unique?: boolean; order?: string }>;\n sourcePath: string;\n}\n\nexport interface SerializedField {\n name: string;\n type: string;\n required: boolean;\n nullable: boolean;\n unique: boolean;\n index: boolean;\n foreignKey?: { table: string; column: string };\n choices?: string[];\n}\n\nexport interface SerializedRelationship {\n name: string;\n type: 'belongs_to' | 'has_many' | 'has_one';\n target: string;\n foreignKey: string;\n inverse?: string;\n through?: string;\n resolved: boolean;\n}\n\nexport interface SerializedRelationshipDefinition {\n name: string;\n table: string;\n from: string;\n to: string;\n selfReferential: boolean;\n fromColumn: string;\n toColumn: string;\n types: Array<{ name: string; inverse?: string; bidirectional: boolean; directed: boolean }>;\n hasTypes: boolean;\n temporal: boolean;\n sourced: boolean;\n onDeleteFrom: string;\n onDeleteTo: string;\n uniqueOn: string[];\n fields: Record<string, SerializedField>;\n queries?: Array<{ by: string[]; unique?: boolean; order?: string }>;\n sourcePath: string;\n}\n\nexport interface SerializedEdge {\n from: string;\n to: string;\n relationship: SerializedRelationship;\n cardinality: '1:1' | '1:N' | 'N:1' | 'N:M';\n bidirectional: boolean;\n}\n\nfunction serializeFields(fields: Map<string, ParsedField>): Record<string, SerializedField> {\n const result: Record<string, SerializedField> = {};\n for (const [key, f] of fields) {\n result[key] = {\n name: f.name,\n type: f.type,\n required: f.required,\n nullable: f.nullable,\n unique: f.unique,\n index: f.index,\n foreignKey: f.foreignKey,\n choices: f.choices,\n };\n }\n return result;\n}\n\nfunction serializeRelationships(\n rels: Map<string, ParsedRelationship>,\n): Record<string, SerializedRelationship> {\n const result: Record<string, SerializedRelationship> = {};\n for (const [key, r] of rels) {\n result[key] = {\n name: r.name,\n type: r.type,\n target: r.target,\n foreignKey: r.foreignKey,\n inverse: r.inverse,\n through: r.through,\n resolved: r.resolved,\n };\n }\n return result;\n}\n\n/**\n * Convert a DomainGraph (with Maps) to a plain JSON-serializable object.\n */\nexport function serializeDomainGraph(graph: DomainGraph): SerializedDomainGraph {\n const entities: Record<string, SerializedEntity> = {};\n for (const [key, entity] of graph.entities) {\n entities[key] = {\n name: entity.name,\n plural: entity.plural,\n table: entity.table,\n family: entity.family,\n fields: serializeFields(entity.fields),\n relationships: serializeRelationships(entity.relationships),\n behaviors: entity.behaviors,\n queries: entity.queries?.map((q) => ({\n by: q.by,\n unique: q.unique,\n order: q.order,\n })),\n sourcePath: entity.sourcePath,\n };\n }\n\n const relationshipDefinitions: Record<string, SerializedRelationshipDefinition> = {};\n for (const [key, relDef] of graph.relationshipDefinitions) {\n relationshipDefinitions[key] = {\n name: relDef.name,\n table: relDef.table,\n from: relDef.from,\n to: relDef.to,\n selfReferential: relDef.selfReferential,\n fromColumn: relDef.fromColumn,\n toColumn: relDef.toColumn,\n types: relDef.types,\n hasTypes: relDef.hasTypes,\n temporal: relDef.temporal,\n sourced: relDef.sourced,\n onDeleteFrom: relDef.onDeleteFrom,\n onDeleteTo: relDef.onDeleteTo,\n uniqueOn: relDef.uniqueOn,\n fields: serializeFields(relDef.fields),\n queries: relDef.queries?.map((q) => ({\n by: q.by,\n unique: q.unique,\n order: q.order,\n })),\n sourcePath: relDef.sourcePath,\n };\n }\n\n return {\n entities,\n relationshipDefinitions,\n edges: graph.edges.map((e) => ({\n from: e.from,\n to: e.to,\n relationship: {\n name: e.relationship.name,\n type: e.relationship.type,\n target: e.relationship.target,\n foreignKey: e.relationship.foreignKey,\n inverse: e.relationship.inverse,\n through: e.relationship.through,\n resolved: e.relationship.resolved,\n },\n cardinality: e.cardinality,\n bidirectional: e.bidirectional,\n })),\n };\n}\n","/**\n * Domain Analyzer Types\n *\n * Core type definitions for the domain analysis tool.\n */\n\nimport type { EntityDefinition } from '../schema/entity-definition.schema';\nimport type { RelationshipDefinition, TypeDirection } from '../schema/relationship-definition.schema';\n\n// ============================================================================\n// Severity Enum\n// ============================================================================\n\nexport type Severity = 'error' | 'warning' | 'info';\n\n// ============================================================================\n// Parsed Entity Types\n// ============================================================================\n\nexport interface ParsedField {\n\tname: string;\n\ttype: string;\n\trequired: boolean;\n\tnullable: boolean;\n\tunique: boolean;\n\tindex: boolean;\n\tforeignKey?: { table: string; column: string };\n\tchoices?: string[];\n\tconstraints: {\n\t\tminLength?: number;\n\t\tmaxLength?: number;\n\t\tmin?: number;\n\t\tmax?: number;\n\t};\n\tui: {\n\t\tlabel?: string;\n\t\ttype?: string;\n\t\timportance?: string;\n\t\tgroup?: string;\n\t\tsortable?: boolean;\n\t\tfilterable?: boolean;\n\t\tvisible?: boolean;\n\t};\n}\n\nexport interface ParsedRelationship {\n\tname: string;\n\ttype: 'belongs_to' | 'has_many' | 'has_one';\n\ttarget: string;\n\tforeignKey: string;\n\tinverse?: string;\n\tthrough?: string; // For transitive relationships: \"owned_opportunities.updates\"\n\tresolved: boolean;\n}\n\nexport type EntityFamily = 'crm-synced' | 'activity' | 'knowledge' | 'metadata';\n\nexport interface ParsedQuery {\n\tby: string[];\n\tunique?: boolean;\n\tselect?: string[];\n\torder?: string;\n\tlimit?: boolean;\n\tvia?: string;\n}\n\nexport interface ParsedProviderSync {\n\tremoteEntity: string;\n\tdirection: 'inbound' | 'outbound' | 'bidirectional';\n\tcdc: boolean;\n\tfieldMapping?: Record<string, string>;\n\treadOnlyFields?: string[];\n}\n\nexport interface ParsedSync {\n\telectric: boolean;\n\tproviders?: Record<string, ParsedProviderSync>;\n}\n\nexport interface ParsedEvent {\n\tname: string;\n\tqueue: string;\n\tbody: Record<string, string>;\n\tgenerateHandler: boolean;\n}\n\nexport interface ParsedEntity {\n\tname: string;\n\tplural: string;\n\ttable: string;\n\tfamily?: EntityFamily;\n\tfolderStructure: 'nested' | 'flat';\n\tfields: Map<string, ParsedField>;\n\trelationships: Map<string, ParsedRelationship>;\n\tbehaviors: string[];\n\tqueries?: ParsedQuery[];\n\tsync?: ParsedSync;\n\tevents?: ParsedEvent[];\n\tsourcePath: string;\n}\n\n// ============================================================================\n// Parsed Relationship Definition Types (first-class junction entities)\n// ============================================================================\n\n/**\n * Direction metadata for a single relationship type.\n * Resolved from the YAML types: block (simple list or object map).\n */\nexport interface ParsedTypeDirection {\n\tname: string;\n\tinverse?: string;\n\tbidirectional: boolean;\n\tdirected: boolean;\n}\n\n/**\n * A parsed relationship definition — a first-class junction entity\n * between two core entities. Loaded from relationship YAML files.\n *\n * This is NOT the same as ParsedRelationship (which is an inline\n * belongs_to/has_many/has_one on an entity). This represents a full\n * junction table with its own fields, types, temporal/sourced flags.\n */\nexport interface ParsedRelationshipDefinition {\n\tname: string;\n\ttable: string;\n\tfrom: string;\n\tto: string;\n\tselfReferential: boolean;\n\n\t// FK column names (derived from from/to)\n\tfromColumn: string;\n\ttoColumn: string;\n\n\t// Type taxonomy\n\ttypes: ParsedTypeDirection[];\n\thasTypes: boolean;\n\n\t// Behavioral flags\n\ttemporal: boolean;\n\tsourced: boolean;\n\n\t// On-delete semantics (ADR-021)\n\tonDeleteFrom: 'restrict' | 'cascade' | 'set_null' | 'no_action';\n\tonDeleteTo: 'restrict' | 'cascade' | 'set_null' | 'no_action';\n\n\t// Unique constraint columns\n\tuniqueOn: string[];\n\n\t// Custom fields (beyond auto-generated)\n\tfields: Map<string, ParsedField>;\n\n\t// Declarative queries\n\tqueries?: ParsedQuery[];\n\n\t// Source file path\n\tsourcePath: string;\n}\n\n// ============================================================================\n// Graph Types\n// ============================================================================\n\nexport interface EntityNode {\n\tid: string;\n\tname: string;\n\tentity: ParsedEntity;\n}\n\nexport interface RelationshipEdge {\n\tfrom: string;\n\tto: string;\n\trelationship: ParsedRelationship;\n\tcardinality: '1:1' | '1:N' | 'N:1' | 'N:M';\n\tbidirectional: boolean;\n}\n\nexport interface DomainGraph {\n\tentities: Map<string, ParsedEntity>;\n\trelationshipDefinitions: Map<string, ParsedRelationshipDefinition>;\n\tedges: RelationshipEdge[];\n}\n\n// ============================================================================\n// Analysis Types\n// ============================================================================\n\nexport interface AnalysisIssue {\n\tseverity: Severity;\n\ttype: string;\n\tentity?: string;\n\tfield?: string;\n\tmessage: string;\n\tpath?: string;\n\tsuggestion?: string;\n}\n\nexport interface DomainStatistics {\n\ttotalEntities: number;\n\ttotalFields: number;\n\ttotalRelationships: number;\n\tfieldsByType: Record<string, number>;\n\trelationshipsByType: Record<string, number>;\n\tentitiesWithBehaviors: number;\n\taverageFieldsPerEntity: number;\n}\n\nexport interface AnalysisResult {\n\tisValid: boolean;\n\tentities: ParsedEntity[];\n\trelationshipDefinitions: ParsedRelationshipDefinition[];\n\tgraph: DomainGraph;\n\tissues: AnalysisIssue[];\n\tstatistics: DomainStatistics;\n}\n\n// ============================================================================\n// Output Format Types\n// ============================================================================\n\nexport type OutputFormat = 'console' | 'json' | 'markdown';\n\n// ============================================================================\n// Transitive Relationship Types\n// ============================================================================\n\nexport interface PathHop {\n\tvia: string; // Intermediate entity name\n\trelationship: string; // Relationship name used at this hop\n\tforeignKey: string; // FK field for this hop\n}\n\nexport interface TransitivePath {\n\tsource: string; // Starting entity (e.g., \"user\")\n\ttarget: string; // Final entity (e.g., \"action_item\")\n\thops: PathHop[]; // Path through the graph\n\tsuggestedName: string; // Generated name (e.g., \"owned_action_items\")\n\tthroughPath: string; // Dot-separated path (e.g., \"meetings.action_items\")\n\tyamlSnippet: string; // Ready-to-paste YAML\n}\n\nexport interface TransitiveSuggestion extends Omit<AnalysisIssue, 'path'> {\n\ttype: 'transitive_suggestion';\n\tpath: TransitivePath;\n}\n\n// ============================================================================\n// Manifest Types\n// ============================================================================\n\nexport interface ManifestField {\n\tname: string;\n\ttype: string;\n\trequired: boolean;\n\tnullable: boolean;\n\tunique: boolean;\n\tindex: boolean;\n\tforeignKey?: { table: string; column: string };\n\tchoices?: string[];\n}\n\nexport interface ManifestRelationship {\n\ttype: 'belongs_to' | 'has_many' | 'has_one';\n\ttarget: string;\n\tforeignKey: string;\n\tthrough?: string;\n\tinverse?: string;\n}\n\nexport interface ManifestEntity {\n\tsourcePath: string;\n\ttable: string;\n\tplural: string;\n\tfields: Record<string, ManifestField>;\n\trelationships: Record<string, ManifestRelationship>;\n\tbehaviors: string[];\n}\n\nexport interface ManifestSuggestion {\n\tid: string; // Stable ID: \"source->target\"\n\tsource: string;\n\ttarget: string;\n\tthroughPath: string;\n\tsuggestedName: string;\n\tyamlSnippet: string;\n\tstatus: 'pending' | 'accepted' | 'skipped';\n\tdetectedAt: string; // ISO timestamp\n\tresolvedAt?: string; // When accepted/skipped\n}\n\nexport interface CodegenManifest {\n\tversion: 1;\n\tgeneratedAt: string;\n\tentityFilesHash: string; // For staleness detection\n\n\tentities: Record<string, ManifestEntity>;\n\n\tgraph: {\n\t\tedges: Array<{\n\t\t\tfrom: string;\n\t\t\tto: string;\n\t\t\trelationship: string;\n\t\t\tcardinality: '1:1' | '1:N' | 'N:1';\n\t\t\tbidirectional: boolean;\n\t\t}>;\n\t\torphans: string[];\n\t\tcycles: string[][];\n\t};\n\n\tsuggestions: {\n\t\ttransitive: ManifestSuggestion[];\n\t};\n\n\tstatistics: {\n\t\ttotalEntities: number;\n\t\ttotalFields: number;\n\t\ttotalRelationships: number;\n\t\ttransitivePathsDetected: number;\n\t};\n}\n","/**\n * Analyzer Module\n *\n * Exports graph building, consistency checking, statistics,\n * transitive suggestion, and manifest utilities.\n */\n\nexport {\n\tbuildDomainGraph,\n\tgetRelatedEntities,\n\tfindOrphanEntities,\n\tfindCircularDependencies,\n\tbuildEntityNodes,\n} from './graph-builder';\n\nexport { checkConsistency } from './consistency-checker';\n\nexport {\n\tcomputeStatistics,\n\tgetFieldBreakdown,\n\tgetUiMetadataCoverage,\n} from './statistics';\n\nexport { suggestTransitiveRelationships } from './transitive-suggester';\n\nexport {\n\tgetManifestDir,\n\tgetManifestPaths,\n\tcomputeEntityFilesHash,\n\treadManifest,\n\twriteManifest,\n\tisManifestStale,\n\tbuildManifest,\n\tupdateSuggestionStatus,\n\tupdateAllSuggestionStatus,\n\tgetPendingSuggestions,\n} from './manifest';\n\nexport { serializeDomainGraph } from './serialize-graph';\nexport type { SerializedDomainGraph } from './serialize-graph';\n\nexport * from './types';\n","/**\n * Console Formatter\n *\n * Pretty terminal output with colors for the domain analysis results.\n */\n\nimport type { AnalysisResult, AnalysisIssue, Severity } from '../analyzer/types';\n\n// ANSI color codes\nconst colors = {\n\treset: '\\x1b[0m',\n\tbold: '\\x1b[1m',\n\tdim: '\\x1b[2m',\n\n\tred: '\\x1b[31m',\n\tgreen: '\\x1b[32m',\n\tyellow: '\\x1b[33m',\n\tblue: '\\x1b[34m',\n\tmagenta: '\\x1b[35m',\n\tcyan: '\\x1b[36m',\n\twhite: '\\x1b[37m',\n\n\tbgRed: '\\x1b[41m',\n\tbgGreen: '\\x1b[42m',\n\tbgYellow: '\\x1b[43m',\n};\n\nfunction color(text: string, ...styles: string[]): string {\n\treturn `${styles.join('')}${text}${colors.reset}`;\n}\n\nfunction severityColor(severity: Severity): string {\n\tswitch (severity) {\n\t\tcase 'error':\n\t\t\treturn colors.red;\n\t\tcase 'warning':\n\t\t\treturn colors.yellow;\n\t\tcase 'info':\n\t\t\treturn colors.cyan;\n\t}\n}\n\nfunction severityIcon(severity: Severity): string {\n\tswitch (severity) {\n\t\tcase 'error':\n\t\t\treturn 'X';\n\t\tcase 'warning':\n\t\t\treturn '!';\n\t\tcase 'info':\n\t\t\treturn 'i';\n\t}\n}\n\n/**\n * Format analysis result for console output\n */\nexport function formatConsole(result: AnalysisResult): string {\n\tconst lines: string[] = [];\n\n\t// Header\n\tlines.push('');\n\tlines.push(color('='.repeat(60), colors.dim));\n\tlines.push(color(' Domain Analysis Report', colors.bold, colors.cyan));\n\tlines.push(color('='.repeat(60), colors.dim));\n\tlines.push('');\n\n\t// Statistics\n\tlines.push(...formatStatistics(result));\n\n\t// Entity summary\n\tlines.push(...formatEntities(result));\n\n\t// Relationships\n\tlines.push(...formatRelationships(result));\n\n\t// Issues\n\tif (result.issues.length > 0) {\n\t\tlines.push(...formatIssues(result.issues));\n\t}\n\n\t// Final status\n\tlines.push('');\n\tlines.push(color('-'.repeat(60), colors.dim));\n\n\tconst errors = result.issues.filter((i) => i.severity === 'error');\n\tconst warnings = result.issues.filter((i) => i.severity === 'warning');\n\tconst infos = result.issues.filter((i) => i.severity === 'info');\n\n\tif (result.isValid) {\n\t\tlines.push(\n\t\t\tcolor(\n\t\t\t\t`[OK] Domain is valid (${warnings.length} warnings, ${infos.length} info)`,\n\t\t\t\tcolors.green\n\t\t\t)\n\t\t);\n\t} else {\n\t\tlines.push(color(`[FAIL] Domain has ${errors.length} errors`, colors.red));\n\t}\n\n\tlines.push(color('-'.repeat(60), colors.dim));\n\tlines.push('');\n\n\treturn lines.join('\\n');\n}\n\nfunction formatStatistics(result: AnalysisResult): string[] {\n\tconst lines: string[] = [];\n\tconst stats = result.statistics;\n\n\tlines.push(color('Statistics:', colors.bold));\n\tlines.push('');\n\tlines.push(` Entities: ${stats.totalEntities}`);\n\tlines.push(\n\t\t` Fields: ${stats.totalFields} (avg ${stats.averageFieldsPerEntity.toFixed(1)}/entity)`\n\t);\n\tlines.push(` Relationships: ${stats.totalRelationships}`);\n\tlines.push(` With behaviors: ${stats.entitiesWithBehaviors}`);\n\tlines.push('');\n\n\t// Field types breakdown\n\tlines.push(' Field types:');\n\tconst sortedTypes = Object.entries(stats.fieldsByType).sort((a, b) => b[1] - a[1]);\n\tfor (const [type, count] of sortedTypes) {\n\t\tconst bar = color('|'.repeat(Math.min(count, 20)), colors.blue);\n\t\tlines.push(` ${type.padEnd(12)} ${bar} ${count}`);\n\t}\n\tlines.push('');\n\n\t// Relationship types breakdown\n\tif (stats.totalRelationships > 0) {\n\t\tlines.push(' Relationship types:');\n\t\tconst sortedRels = Object.entries(stats.relationshipsByType).sort((a, b) => b[1] - a[1]);\n\t\tfor (const [type, count] of sortedRels) {\n\t\t\tconst bar = color('|'.repeat(Math.min(count, 20)), colors.magenta);\n\t\t\tlines.push(` ${type.padEnd(12)} ${bar} ${count}`);\n\t\t}\n\t\tlines.push('');\n\t}\n\n\treturn lines;\n}\n\nfunction formatEntities(result: AnalysisResult): string[] {\n\tconst lines: string[] = [];\n\n\tlines.push(color('Entities:', colors.bold));\n\tlines.push('');\n\n\tfor (const entity of result.entities) {\n\t\tconst fieldCount = entity.fields.size;\n\t\tconst relCount = entity.relationships.size;\n\t\tlines.push(\n\t\t\t` ${color(entity.name, colors.cyan)} (${fieldCount} fields, ${relCount} relationships)`\n\t\t);\n\t\tif (entity.behaviors.length > 0) {\n\t\t\tlines.push(color(` behaviors: ${entity.behaviors.join(', ')}`, colors.dim));\n\t\t}\n\t}\n\tlines.push('');\n\n\treturn lines;\n}\n\nfunction formatRelationships(result: AnalysisResult): string[] {\n\tconst lines: string[] = [];\n\n\tif (result.graph.edges.length === 0) {\n\t\treturn lines;\n\t}\n\n\tlines.push(color('Relationships:', colors.bold));\n\tlines.push('');\n\n\tfor (const edge of result.graph.edges) {\n\t\tconst arrow = getCardinalityArrow(edge.cardinality);\n\t\tconst bidir = edge.bidirectional ? color(' (bidirectional)', colors.dim) : '';\n\t\tlines.push(\n\t\t\t` ${edge.from.padEnd(20)} ${arrow} ${edge.to} ${color(`(${edge.relationship.type})`, colors.dim)}${bidir}`\n\t\t);\n\t}\n\tlines.push('');\n\n\treturn lines;\n}\n\nfunction getCardinalityArrow(cardinality: string): string {\n\tswitch (cardinality) {\n\t\tcase '1:N':\n\t\t\treturn color('--<', colors.magenta);\n\t\tcase 'N:1':\n\t\t\treturn color('>--', colors.magenta);\n\t\tcase '1:1':\n\t\t\treturn color('---', colors.magenta);\n\t\tcase 'N:M':\n\t\t\treturn color('>-<', colors.magenta);\n\t\tdefault:\n\t\t\treturn color('-->', colors.magenta);\n\t}\n}\n\nfunction formatIssues(issues: AnalysisIssue[]): string[] {\n\tconst lines: string[] = [];\n\n\t// Group by severity\n\tconst errors = issues.filter((i) => i.severity === 'error');\n\tconst warnings = issues.filter((i) => i.severity === 'warning');\n\tconst infos = issues.filter((i) => i.severity === 'info');\n\n\tif (errors.length > 0) {\n\t\tlines.push(color(`Errors (${errors.length}):`, colors.bold, colors.red));\n\t\tlines.push('');\n\t\tlines.push(...formatIssueList(errors, 'error'));\n\t\tlines.push('');\n\t}\n\n\tif (warnings.length > 0) {\n\t\tlines.push(color(`Warnings (${warnings.length}):`, colors.bold, colors.yellow));\n\t\tlines.push('');\n\t\tlines.push(...formatIssueList(warnings, 'warning'));\n\t\tlines.push('');\n\t}\n\n\tif (infos.length > 0) {\n\t\tlines.push(color(`Info (${infos.length}):`, colors.bold, colors.cyan));\n\t\tlines.push('');\n\t\tlines.push(...formatIssueList(infos, 'info', 5)); // Only show first 5 info messages\n\t\tlines.push('');\n\t}\n\n\treturn lines;\n}\n\nfunction formatIssueList(\n\tissues: AnalysisIssue[],\n\tseverity: Severity,\n\tlimit?: number\n): string[] {\n\tconst lines: string[] = [];\n\tconst displayIssues = limit ? issues.slice(0, limit) : issues;\n\n\t// Group by type\n\tconst byType = new Map<string, AnalysisIssue[]>();\n\tfor (const issue of displayIssues) {\n\t\tconst list = byType.get(issue.type) ?? [];\n\t\tlist.push(issue);\n\t\tbyType.set(issue.type, list);\n\t}\n\n\tfor (const [type, typeIssues] of byType) {\n\t\tlines.push(color(` ${type} (${typeIssues.length}):`, colors.dim));\n\n\t\tfor (const issue of typeIssues.slice(0, 5)) {\n\t\t\tconst location = issue.entity\n\t\t\t\t? `${issue.entity}${issue.field ? '.' + issue.field : ''}`\n\t\t\t\t: issue.path ?? 'unknown';\n\n\t\t\tconst icon = color(`[${severityIcon(severity)}]`, severityColor(severity));\n\t\t\tlines.push(` ${icon} ${color(location, colors.bold)}: ${issue.message}`);\n\n\t\t\tif (issue.suggestion) {\n\t\t\t\tlines.push(color(` -> ${issue.suggestion}`, colors.dim));\n\t\t\t}\n\t\t}\n\n\t\tif (typeIssues.length > 5) {\n\t\t\tlines.push(color(` ... and ${typeIssues.length - 5} more`, colors.dim));\n\t\t}\n\t}\n\n\tif (limit && issues.length > limit) {\n\t\tlines.push(color(` ... and ${issues.length - limit} more info messages`, colors.dim));\n\t}\n\n\treturn lines;\n}\n","/**\n * JSON Formatter\n *\n * Machine-readable JSON output for the domain analysis results.\n */\n\nimport type { AnalysisResult, ParsedEntity, DomainGraph } from '../analyzer/types';\n\n/**\n * Helper to convert Maps to plain objects for JSON serialization\n */\nfunction mapToObject<K extends string, V>(map: Map<K, V>): Record<K, V> {\n\tconst obj = {} as Record<K, V>;\n\tfor (const [key, value] of map) {\n\t\tobj[key] = value;\n\t}\n\treturn obj;\n}\n\n/**\n * Convert ParsedEntity to a JSON-serializable format\n */\nfunction serializeEntity(entity: ParsedEntity): Record<string, unknown> {\n\treturn {\n\t\tname: entity.name,\n\t\tplural: entity.plural,\n\t\ttable: entity.table,\n\t\tfolderStructure: entity.folderStructure,\n\t\tfields: mapToObject(entity.fields),\n\t\trelationships: mapToObject(entity.relationships),\n\t\tbehaviors: entity.behaviors,\n\t\tsourcePath: entity.sourcePath,\n\t};\n}\n\n/**\n * Convert DomainGraph to a JSON-serializable format\n */\nfunction serializeGraph(graph: DomainGraph): Record<string, unknown> {\n\tconst entities: Record<string, unknown> = {};\n\tfor (const [name, entity] of graph.entities) {\n\t\tentities[name] = serializeEntity(entity);\n\t}\n\n\treturn {\n\t\tentities,\n\t\tedges: graph.edges,\n\t};\n}\n\n/**\n * Format analysis result as JSON string\n */\nexport function formatJson(result: AnalysisResult, pretty = true): string {\n\tconst output = {\n\t\tisValid: result.isValid,\n\t\tsummary: {\n\t\t\tentities: result.statistics.totalEntities,\n\t\t\tfields: result.statistics.totalFields,\n\t\t\trelationships: result.statistics.totalRelationships,\n\t\t\terrors: result.issues.filter((i) => i.severity === 'error').length,\n\t\t\twarnings: result.issues.filter((i) => i.severity === 'warning').length,\n\t\t\tinfo: result.issues.filter((i) => i.severity === 'info').length,\n\t\t},\n\t\tentities: result.entities.map(serializeEntity),\n\t\tgraph: serializeGraph(result.graph),\n\t\tissues: result.issues,\n\t\tstatistics: result.statistics,\n\t\ttimestamp: new Date().toISOString(),\n\t};\n\n\treturn pretty ? JSON.stringify(output, null, 2) : JSON.stringify(output);\n}\n\n/**\n * Format only statistics as JSON\n */\nexport function formatStatsJson(result: AnalysisResult, pretty = true): string {\n\tconst output = {\n\t\tstatistics: result.statistics,\n\t\tisValid: result.isValid,\n\t\tissueCount: {\n\t\t\terrors: result.issues.filter((i) => i.severity === 'error').length,\n\t\t\twarnings: result.issues.filter((i) => i.severity === 'warning').length,\n\t\t\tinfo: result.issues.filter((i) => i.severity === 'info').length,\n\t\t},\n\t\ttimestamp: new Date().toISOString(),\n\t};\n\n\treturn pretty ? JSON.stringify(output, null, 2) : JSON.stringify(output);\n}\n\n/**\n * Format only issues as JSON\n */\nexport function formatIssuesJson(result: AnalysisResult, pretty = true): string {\n\tconst output = {\n\t\tisValid: result.isValid,\n\t\tissues: result.issues,\n\t\ttimestamp: new Date().toISOString(),\n\t};\n\n\treturn pretty ? JSON.stringify(output, null, 2) : JSON.stringify(output);\n}\n","/**\n * Markdown Formatter\n *\n * Documentation output with Mermaid diagrams for the domain analysis results.\n */\n\nimport type { AnalysisResult, ParsedEntity, RelationshipEdge } from '../analyzer/types';\n\n/**\n * Format analysis result as Markdown documentation\n */\nexport function formatMarkdown(result: AnalysisResult): string {\n\tconst lines: string[] = [];\n\n\t// Title\n\tlines.push('# Domain Model Documentation');\n\tlines.push('');\n\tlines.push(`Generated: ${new Date().toISOString()}`);\n\tlines.push('');\n\n\t// Overview statistics\n\tlines.push('## Overview');\n\tlines.push('');\n\tlines.push('| Metric | Value |');\n\tlines.push('|--------|-------|');\n\tlines.push(`| Entities | ${result.statistics.totalEntities} |`);\n\tlines.push(`| Total Fields | ${result.statistics.totalFields} |`);\n\tlines.push(`| Total Relationships | ${result.statistics.totalRelationships} |`);\n\tlines.push(\n\t\t`| Avg Fields/Entity | ${result.statistics.averageFieldsPerEntity.toFixed(1)} |`\n\t);\n\tlines.push('');\n\n\t// Field type distribution\n\tlines.push('### Field Type Distribution');\n\tlines.push('');\n\tlines.push('| Type | Count |');\n\tlines.push('|------|-------|');\n\tconst sortedTypes = Object.entries(result.statistics.fieldsByType).sort(\n\t\t(a, b) => b[1] - a[1]\n\t);\n\tfor (const [type, count] of sortedTypes) {\n\t\tlines.push(`| ${type} | ${count} |`);\n\t}\n\tlines.push('');\n\n\t// Relationship type distribution\n\tif (result.statistics.totalRelationships > 0) {\n\t\tlines.push('### Relationship Type Distribution');\n\t\tlines.push('');\n\t\tlines.push('| Type | Count |');\n\t\tlines.push('|------|-------|');\n\t\tconst sortedRels = Object.entries(result.statistics.relationshipsByType).sort(\n\t\t\t(a, b) => b[1] - a[1]\n\t\t);\n\t\tfor (const [type, count] of sortedRels) {\n\t\t\tlines.push(`| ${type} | ${count} |`);\n\t\t}\n\t\tlines.push('');\n\t}\n\n\t// Entity Relationship Diagram\n\tlines.push('## Entity Relationship Diagram');\n\tlines.push('');\n\tlines.push('```mermaid');\n\tlines.push(...generateMermaidErDiagram(result));\n\tlines.push('```');\n\tlines.push('');\n\n\t// Entities\n\tlines.push('## Entities');\n\tlines.push('');\n\n\tfor (const entity of result.entities) {\n\t\tlines.push(...formatEntitySection(entity));\n\t}\n\n\t// Issues\n\tconst errors = result.issues.filter((i) => i.severity === 'error');\n\tconst warnings = result.issues.filter((i) => i.severity === 'warning');\n\tconst infos = result.issues.filter((i) => i.severity === 'info');\n\n\tif (result.issues.length > 0) {\n\t\tlines.push('## Analysis Issues');\n\t\tlines.push('');\n\n\t\tif (errors.length > 0) {\n\t\t\tlines.push('### Errors');\n\t\t\tlines.push('');\n\t\t\tfor (const issue of errors) {\n\t\t\t\tconst location = issue.entity\n\t\t\t\t\t? `**${issue.entity}${issue.field ? '.' + issue.field : ''}**`\n\t\t\t\t\t: issue.path ?? 'unknown';\n\t\t\t\tlines.push(`- [${issue.type}] ${location}: ${issue.message}`);\n\t\t\t\tif (issue.suggestion) {\n\t\t\t\t\tlines.push(` - Suggestion: ${issue.suggestion}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlines.push('');\n\t\t}\n\n\t\tif (warnings.length > 0) {\n\t\t\tlines.push('### Warnings');\n\t\t\tlines.push('');\n\t\t\tfor (const issue of warnings) {\n\t\t\t\tconst location = issue.entity\n\t\t\t\t\t? `**${issue.entity}${issue.field ? '.' + issue.field : ''}**`\n\t\t\t\t\t: issue.path ?? 'unknown';\n\t\t\t\tlines.push(`- [${issue.type}] ${location}: ${issue.message}`);\n\t\t\t\tif (issue.suggestion) {\n\t\t\t\t\tlines.push(` - Suggestion: ${issue.suggestion}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlines.push('');\n\t\t}\n\n\t\tif (infos.length > 0) {\n\t\t\tlines.push('### Info');\n\t\t\tlines.push('');\n\t\t\tlines.push('<details>');\n\t\t\tlines.push('<summary>Show info messages</summary>');\n\t\t\tlines.push('');\n\t\t\tfor (const issue of infos) {\n\t\t\t\tconst location = issue.entity\n\t\t\t\t\t? `**${issue.entity}${issue.field ? '.' + issue.field : ''}**`\n\t\t\t\t\t: issue.path ?? 'unknown';\n\t\t\t\tlines.push(`- [${issue.type}] ${location}: ${issue.message}`);\n\t\t\t}\n\t\t\tlines.push('');\n\t\t\tlines.push('</details>');\n\t\t\tlines.push('');\n\t\t}\n\t}\n\n\treturn lines.join('\\n');\n}\n\n/**\n * Format a single entity section\n */\nfunction formatEntitySection(entity: ParsedEntity): string[] {\n\tconst lines: string[] = [];\n\n\tlines.push(`### ${entity.name}`);\n\tlines.push('');\n\tlines.push(`**Table:** \\`${entity.table}\\``);\n\tlines.push(`**Plural:** ${entity.plural}`);\n\tif (entity.behaviors.length > 0) {\n\t\tlines.push(`**Behaviors:** ${entity.behaviors.join(', ')}`);\n\t}\n\tlines.push('');\n\n\t// Fields table\n\tlines.push('#### Fields');\n\tlines.push('');\n\tlines.push('| Name | Type | Required | Nullable | Index | Foreign Key |');\n\tlines.push('|------|------|----------|----------|-------|-------------|');\n\n\tfor (const [name, field] of entity.fields) {\n\t\tconst required = field.required ? 'Yes' : '';\n\t\tconst nullable = field.nullable ? 'Yes' : '';\n\t\tconst index = field.index ? 'Yes' : field.unique ? 'Unique' : '';\n\t\tconst fk = field.foreignKey ? `${field.foreignKey.table}.${field.foreignKey.column}` : '';\n\t\tlines.push(`| ${name} | ${field.type} | ${required} | ${nullable} | ${index} | ${fk} |`);\n\t}\n\tlines.push('');\n\n\t// Relationships\n\tif (entity.relationships.size > 0) {\n\t\tlines.push('#### Relationships');\n\t\tlines.push('');\n\t\tlines.push('| Name | Type | Target | Foreign Key |');\n\t\tlines.push('|------|------|--------|-------------|');\n\n\t\tfor (const [name, rel] of entity.relationships) {\n\t\t\tlines.push(`| ${name} | ${rel.type} | ${rel.target} | ${rel.foreignKey} |`);\n\t\t}\n\t\tlines.push('');\n\t}\n\n\treturn lines;\n}\n\n/**\n * Generate Mermaid ER diagram\n */\nfunction generateMermaidErDiagram(result: AnalysisResult): string[] {\n\tconst lines: string[] = [];\n\n\tlines.push('erDiagram');\n\n\t// Define entities with their fields\n\tfor (const entity of result.entities) {\n\t\tconst entityName = entity.name.toUpperCase();\n\t\tlines.push(` ${entityName} {`);\n\n\t\t// Show key fields only (to keep diagram readable)\n\t\tconst keyFields = Array.from(entity.fields.entries())\n\t\t\t.filter(\n\t\t\t\t([name, field]) =>\n\t\t\t\t\tfield.foreignKey || field.unique || field.index || name === 'id' || name === 'name'\n\t\t\t)\n\t\t\t.slice(0, 6); // Limit to 6 fields\n\n\t\tfor (const [name, field] of keyFields) {\n\t\t\tconst typeStr = field.type;\n\t\t\tconst pk = name === 'id' ? 'PK' : '';\n\t\t\tconst fk = field.foreignKey ? 'FK' : '';\n\t\t\tconst marker = pk || fk ? ` \"${pk}${fk}\"` : '';\n\t\t\tlines.push(` ${typeStr} ${name}${marker}`);\n\t\t}\n\n\t\tif (entity.fields.size > keyFields.length) {\n\t\t\tlines.push(` string _more_fields`);\n\t\t}\n\n\t\tlines.push(' }');\n\t}\n\n\t// Add relationships\n\tfor (const edge of result.graph.edges) {\n\t\tconst from = edge.from.toUpperCase();\n\t\tconst to = edge.to.toUpperCase();\n\t\tconst cardinalitySymbol = getCardinalitySymbol(edge.cardinality);\n\t\tconst label = edge.relationship.name;\n\n\t\tlines.push(` ${from} ${cardinalitySymbol} ${to} : \"${label}\"`);\n\t}\n\n\treturn lines;\n}\n\n/**\n * Get Mermaid cardinality symbol\n */\nfunction getCardinalitySymbol(cardinality: string): string {\n\tswitch (cardinality) {\n\t\tcase '1:N':\n\t\t\treturn '||--o{';\n\t\tcase 'N:1':\n\t\t\treturn '}o--||';\n\t\tcase '1:1':\n\t\t\treturn '||--||';\n\t\tcase 'N:M':\n\t\t\treturn '}o--o{';\n\t\tdefault:\n\t\t\treturn '||--o{';\n\t}\n}\n\n/**\n * Generate a simple relationship graph in Mermaid\n */\nexport function formatMermaidGraph(result: AnalysisResult): string {\n\tconst lines: string[] = [];\n\n\tlines.push('```mermaid');\n\tlines.push('graph LR');\n\n\t// Style definitions\n\tlines.push(' classDef entity fill:#e1f5fe,stroke:#01579b');\n\n\t// Add entities as nodes\n\tfor (const entity of result.entities) {\n\t\tlines.push(` ${entity.name}[\"${entity.name}\\\\n(${entity.fields.size} fields)\"]`);\n\t}\n\n\t// Add relationships as edges\n\tfor (const edge of result.graph.edges) {\n\t\tconst style = edge.bidirectional ? '<-->' : '-->';\n\t\tlines.push(` ${edge.from} ${style}|${edge.relationship.type}| ${edge.to}`);\n\t}\n\n\t// Apply styles\n\tconst entityList = result.entities.map((e) => e.name).join(',');\n\tif (entityList) {\n\t\tlines.push(` class ${entityList} entity`);\n\t}\n\n\tlines.push('```');\n\n\treturn lines.join('\\n');\n}\n","/**\n * Output Module\n *\n * Exports formatting utilities for different output formats.\n */\n\nexport { formatConsole } from './console-formatter';\nexport { formatJson, formatStatsJson, formatIssuesJson } from './json-formatter';\nexport { formatMarkdown, formatMermaidGraph } from './markdown-formatter';\n","/**\n * Entity Codegen & Domain Analyzer\n *\n * A validation and analysis tool for entity YAML definitions.\n * Parses entities, builds a relationship graph, and detects issues.\n */\n\nimport { loadEntities, loadRelationships, resolveReferences, resolveRelationshipReferences } from './parser';\nimport { buildDomainGraph, checkConsistency, computeStatistics } from './analyzer';\nimport type { AnalysisResult, OutputFormat } from './analyzer/types';\n\n/**\n * Analyze a domain from entity and relationship YAML files\n */\nexport async function analyzeDomain(\n\tentitiesDir: string,\n\trelationshipsDir?: string,\n): Promise<AnalysisResult> {\n\t// Load and parse all entity files\n\tconst { entities, issues: loadIssues } = loadEntities(entitiesDir);\n\n\t// Load relationship definitions (optional — directory may not exist)\n\tconst { relationships: relationshipDefinitions, issues: relLoadIssues } =\n\t\trelationshipsDir\n\t\t\t? loadRelationships(relationshipsDir)\n\t\t\t: { relationships: [], issues: [] };\n\n\t// Resolve cross-entity references\n\tconst resolveIssues = resolveReferences(entities);\n\n\t// Resolve relationship endpoint references\n\tconst relResolveIssues = resolveRelationshipReferences(\n\t\trelationshipDefinitions,\n\t\tentities,\n\t);\n\n\t// Build relationship graph (includes both inline and first-class relationships)\n\tconst graph = buildDomainGraph(entities, relationshipDefinitions);\n\n\t// Check consistency\n\tconst consistencyIssues = checkConsistency(graph);\n\n\t// Compute statistics\n\tconst statistics = computeStatistics(graph);\n\n\t// Combine all issues\n\tconst allIssues = [\n\t\t...loadIssues,\n\t\t...relLoadIssues,\n\t\t...resolveIssues,\n\t\t...relResolveIssues,\n\t\t...consistencyIssues,\n\t];\n\n\t// Determine validity (only errors make it invalid)\n\tconst hasErrors = allIssues.some((i) => i.severity === 'error');\n\n\treturn {\n\t\tisValid: !hasErrors,\n\t\tentities,\n\t\trelationshipDefinitions,\n\t\tgraph,\n\t\tissues: allIssues,\n\t\tstatistics,\n\t};\n}\n\n/**\n * Validate entity files without full analysis\n * Returns true if all files parse successfully\n */\nexport function validateEntities(entitiesDir: string): {\n\tvalid: boolean;\n\terrors: string[];\n} {\n\tconst { entities, issues } = loadEntities(entitiesDir);\n\tconst errors = issues\n\t\t.filter((i) => i.severity === 'error')\n\t\t.map((i) => i.message);\n\n\treturn {\n\t\tvalid: errors.length === 0,\n\t\terrors,\n\t};\n}\n\n// Re-export types\nexport * from './analyzer/types';\n\n// Re-export parser utilities\nexport { loadEntities, loadRelationships, loadEntityFromYaml, loadRelationshipFromYaml } from './parser';\n\n// Re-export analyzer utilities\nexport {\n\tbuildDomainGraph,\n\tgetRelatedEntities,\n\tfindOrphanEntities,\n\tfindCircularDependencies,\n\tcheckConsistency,\n\tcomputeStatistics,\n} from './analyzer';\n\n// Re-export formatters\nexport {\n\tformatConsole,\n\tformatJson,\n\tformatMarkdown,\n\tformatMermaidGraph,\n} from './formatters';\n","/**\n * Hygen invocation helper — shared between `entity` and `subsystem` nouns.\n *\n * Extracted verbatim from the legacy src/cli.ts so behavior is identical\n * during the transition. We shell out to `bunx hygen <generator> <action>`\n * with HYGEN_TMPLS pointing at our templates directory.\n */\n\nimport { execSync, type ExecSyncOptions } from 'node:child_process';\nimport { join } from 'node:path';\n\nexport interface HygenInvocation {\n\t/** e.g. 'entity' */\n\tgenerator: string;\n\t/** e.g. 'new' */\n\taction: string;\n\t/** Absolute path to the templates/ directory. Defaults to bundled templates. */\n\ttemplateRoot?: string;\n\t/** Extra positional args passed after `<generator> <action>` */\n\targs?: string[];\n\t/** Extra env vars merged onto process.env */\n\tenv?: NodeJS.ProcessEnv;\n\t/** Working directory Hygen executes in. Defaults to process.cwd(). */\n\tcwd?: string;\n\t/** If false, suppresses child stdio inheritance. Defaults to true. */\n\tinherit?: boolean;\n}\n\nexport interface HygenResult {\n\tok: boolean;\n\tcommand: string;\n\tstdout?: string;\n\tstderr?: string;\n}\n\nfunction defaultTemplateRoot(): string {\n\t// src/cli/shared/hygen.ts → ../../../templates\n\treturn join(import.meta.dirname, '..', '..', '..', 'templates');\n}\n\nfunction quoteArg(a: string): string {\n\tif (a === '' || /[\\s\"'$`\\\\]/.test(a)) {\n\t\treturn `\"${a.replace(/([\"$`\\\\])/g, '\\\\$1')}\"`;\n\t}\n\treturn a;\n}\n\n/**\n * Invoke Hygen synchronously, inheriting stdio by default (so users see the\n * generator's own output). Returns {ok:false} on non-zero exit.\n */\nexport function invokeHygen(opts: HygenInvocation): HygenResult {\n\tconst templateRoot = opts.templateRoot ?? defaultTemplateRoot();\n\tconst extra = (opts.args ?? []).map(quoteArg).join(' ');\n\tconst command = `bunx hygen ${opts.generator} ${opts.action}${extra ? ' ' + extra : ''}`;\n\n\tconst execOpts: ExecSyncOptions = {\n\t\tcwd: opts.cwd ?? process.cwd(),\n\t\tenv: { ...process.env, HYGEN_TMPLS: templateRoot, ...(opts.env ?? {}) },\n\t\tstdio: opts.inherit === false ? 'pipe' : 'inherit',\n\t};\n\n\ttry {\n\t\tconst out = execSync(command, execOpts);\n\t\treturn {\n\t\t\tok: true,\n\t\t\tcommand,\n\t\t\tstdout: out ? out.toString() : undefined,\n\t\t};\n\t} catch (err: unknown) {\n\t\tconst e = err as {\n\t\t\tstdout?: Buffer | string;\n\t\t\tstderr?: Buffer | string;\n\t\t\tmessage?: string;\n\t\t};\n\t\treturn {\n\t\t\tok: false,\n\t\t\tcommand,\n\t\t\tstdout: e.stdout ? e.stdout.toString() : undefined,\n\t\t\tstderr: e.stderr ? e.stderr.toString() : e.message,\n\t\t};\n\t}\n}\n\n/**\n * Convenience wrapper for the most common pattern — generating one entity\n * from a YAML path.\n */\nexport function invokeEntityNew(absoluteYamlPath: string, cwd?: string): HygenResult {\n\treturn invokeHygen({\n\t\tgenerator: 'entity',\n\t\taction: 'new',\n\t\targs: ['--yaml', absoluteYamlPath],\n\t\tcwd,\n\t});\n}\n\n/**\n * Convenience wrapper for generating one relationship from a YAML path.\n */\nexport function invokeRelationshipNew(absoluteYamlPath: string, cwd?: string): HygenResult {\n\treturn invokeHygen({\n\t\tgenerator: 'relationship',\n\t\taction: 'new',\n\t\targs: ['--yaml', absoluteYamlPath],\n\t\tcwd,\n\t});\n}\n","/**\n * Git safety check — warn before overwriting files with uncommitted changes.\n *\n * Used by `entity new` and `subsystem install` to prevent silent clobbering.\n * Non-git projects return { clean: true, dirty: [] }.\n */\n\nimport { execSync } from 'node:child_process';\nimport path from 'node:path';\n\nexport interface GitSafetyResult {\n\tclean: boolean;\n\tdirty: string[];\n\tinRepo: boolean;\n}\n\nfunction isInsideGitRepo(cwd: string): boolean {\n\ttry {\n\t\texecSync('git rev-parse --is-inside-work-tree', {\n\t\t\tcwd,\n\t\t\tstdio: ['ignore', 'pipe', 'ignore'],\n\t\t});\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Run `git status --porcelain` against the given paths. Returns the subset\n * of paths that have modifications. An empty `paths` array returns a clean\n * result.\n */\nexport function checkGitSafety(paths: string[], cwd: string = process.cwd()): GitSafetyResult {\n\tif (paths.length === 0) return { clean: true, dirty: [], inRepo: isInsideGitRepo(cwd) };\n\n\tif (!isInsideGitRepo(cwd)) {\n\t\treturn { clean: true, dirty: [], inRepo: false };\n\t}\n\n\t// Normalize paths to relative POSIX paths — git status prefers them.\n\tconst rels = paths.map((p) => {\n\t\tconst abs = path.isAbsolute(p) ? p : path.resolve(cwd, p);\n\t\treturn path.relative(cwd, abs).replace(/\\\\/g, '/');\n\t});\n\n\t// Build safe argument list; execFile-style via execSync with `--` separator.\n\tconst argStr = rels.map((r) => `\"${r.replace(/\"/g, '\\\\\"')}\"`).join(' ');\n\tlet output = '';\n\ttry {\n\t\toutput = execSync(`git status --porcelain -- ${argStr}`, {\n\t\t\tcwd,\n\t\t\tstdio: ['ignore', 'pipe', 'ignore'],\n\t\t}).toString();\n\t} catch {\n\t\treturn { clean: true, dirty: [], inRepo: true };\n\t}\n\n\tconst dirty: string[] = [];\n\tfor (const line of output.split('\\n')) {\n\t\tif (!line.trim()) continue;\n\t\t// porcelain lines: \"XY path\" (X+Y = 2 status chars, then space, then path)\n\t\tconst match = line.match(/^..\\s(.+)$/);\n\t\tif (match) dirty.push(match[1].trim());\n\t}\n\n\treturn { clean: dirty.length === 0, dirty, inRepo: true };\n}\n","/**\n * Barrel generator — writes codegen-owned barrel files that aggregate every\n * entity's NestJS module and Drizzle entity schema.\n *\n * Context (see ADR-017): Hygen injects into user-authored `app.module.ts` and\n * `schema.ts` were fragile — they corrupted files silently when the anchors\n * weren't where the template expected. We now own two files instead:\n *\n * <generated>/modules.ts — exports a frozen array of every entity module\n * <generated>/schema.ts — re-exports every entity's drizzle schema file\n *\n * The user wires these up exactly once:\n *\n * // app.module.ts\n * import { GENERATED_MODULES } from './generated/modules';\n * @Module({ imports: [DatabaseModule, ...GENERATED_MODULES] })\n *\n * // schema.ts\n * export * from './generated/schema';\n *\n * Every `entity new` / `entity new --all` invocation fully regenerates both\n * barrels from the full entity set. Deterministic, no state tracking, no\n * mutation of user files.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { Context } from './context.js';\nimport { loadEntityFromYaml } from '../../utils/yaml-loader.js';\nimport type { EntityDefinition } from '../../schema/entity-definition.schema.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type Architecture = 'clean' | 'clean-lite-ps';\n\nexport interface BarrelGeneratorOptions {\n\tctx: Context;\n\t/** Absolute path to the entities directory. */\n\tentitiesDir: string;\n\t/** Absolute path to the directory the barrels should be written into. */\n\tgeneratedDir: string;\n\t/** Architecture flavor — drives where entity modules live on disk. */\n\tarchitecture: Architecture;\n\t/**\n\t * Backend source root, relative to project root. Used to compute module\n\t * file paths for the 'clean' architecture. Ignored for 'clean-lite-ps'.\n\t * Defaults to 'app/backend/src' to match src/config/locations.mjs.\n\t */\n\tbackendSrc?: string;\n\t/** If true, compute content but don't touch the filesystem. */\n\tdryRun?: boolean;\n}\n\nexport interface BarrelResult {\n\tmodulesBarrel: string;\n\tschemaBarrel: string;\n\tentityCount: number;\n\t/** Planned file contents — always populated, useful for dry-run reports. */\n\tmodulesContent: string;\n\tschemaContent: string;\n\t/** True when the barrels were actually written to disk. */\n\twritten: boolean;\n}\n\ninterface EntityInfo {\n\tname: string;\n\tplural: string;\n}\n\n// ---------------------------------------------------------------------------\n// Case helpers — intentionally local to avoid a dependency on case-converters.mjs\n// from a TS module. Identical semantics for the snake/kebab → Pascal case path\n// we actually exercise here.\n// ---------------------------------------------------------------------------\n\nfunction toPascalCase(input: string): string {\n\treturn input\n\t\t.split(/[-_\\s]+/)\n\t\t.filter(Boolean)\n\t\t.map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n\t\t.join('');\n}\n\nfunction toKebabCase(input: string): string {\n\treturn input\n\t\t.replace(/([a-z])([A-Z])/g, '$1-$2')\n\t\t.replace(/[_\\s]+/g, '-')\n\t\t.toLowerCase();\n}\n\n// ---------------------------------------------------------------------------\n// Entity discovery\n// ---------------------------------------------------------------------------\n\nexport function listEntityYamls(entitiesDir: string): string[] {\n\tif (!fs.existsSync(entitiesDir)) return [];\n\treturn fs\n\t\t.readdirSync(entitiesDir)\n\t\t.filter((f) => f.endsWith('.yaml') || f.endsWith('.yml'))\n\t\t.map((f) => path.join(entitiesDir, f))\n\t\t.sort();\n}\n\nfunction collectEntities(entitiesDir: string): EntityInfo[] {\n\tconst files = listEntityYamls(entitiesDir);\n\tconst entities: EntityInfo[] = [];\n\tfor (const file of files) {\n\t\tconst result = loadEntityFromYaml(file);\n\t\tif (!result.success) continue;\n\t\tconst def: EntityDefinition = result.definition;\n\t\tentities.push({\n\t\t\tname: def.entity.name,\n\t\t\tplural: def.entity.plural,\n\t\t});\n\t}\n\t// Deterministic: sort by singular name.\n\tentities.sort((a, b) => a.name.localeCompare(b.name));\n\treturn entities;\n}\n\n// ---------------------------------------------------------------------------\n// Path computation per architecture\n// ---------------------------------------------------------------------------\n\n/**\n * Where each entity's module + schema file lives, relative to project root.\n *\n * Must match the output of the actual Hygen templates:\n * - clean-lite-ps: modules/<plural>/<plural>.module.ts\n * modules/<plural>/<name>.entity.ts\n * - clean: src/infrastructure/modules/<plural>.module.ts\n * src/infrastructure/persistence/drizzle/<plural>.schema.ts\n *\n * Note: the `clean` paths mirror the defaults in src/config/locations.mjs and\n * the backend template set's output paths. If a project overrides those via\n * `locations:` in codegen.config.yaml, the barrel will still point at the\n * default locations — a known limitation documented in ADR-017.\n */\nfunction entityFilePaths(\n\tinfo: EntityInfo,\n\tarchitecture: Architecture,\n\tbackendSrc: string\n): {\n\tmoduleFile: string;\n\tmoduleClass: string;\n\tschemaFile: string;\n} {\n\tconst name = info.name;\n\tconst plural = info.plural;\n\tconst nameKebab = toKebabCase(name);\n\tconst pluralKebab = toKebabCase(plural);\n\n\tif (architecture === 'clean-lite-ps') {\n\t\t// Clean-Lite-PS templates currently emit directories/files using the raw\n\t\t// snake_case `plural`/`name` values (see templates/entity/new/clean-lite-ps/\n\t\t// prompt-extension.js). The barrel must match that on-disk layout.\n\t\treturn {\n\t\t\tmoduleFile: `modules/${plural}/${plural}.module.ts`,\n\t\t\tmoduleClass: `${toPascalCase(plural)}Module`,\n\t\t\t// Drizzle entity schema lives alongside the entity file in clean-lite-ps.\n\t\t\tschemaFile: `modules/${plural}/${name}.entity.ts`,\n\t\t};\n\t}\n\n\t// 'clean' — full Clean Architecture. Paths mirror src/config/locations.mjs\n\t// defaults; a `paths.backend_src` override in codegen.config.yaml is honored\n\t// via the `backendSrc` parameter.\n\treturn {\n\t\tmoduleFile: `${backendSrc}/infrastructure/modules/${pluralKebab}.module.ts`,\n\t\tmoduleClass: `${toPascalCase(plural)}Module`,\n\t\tschemaFile: `${backendSrc}/infrastructure/persistence/drizzle/${pluralKebab}.schema.ts`,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Content builders\n// ---------------------------------------------------------------------------\n\nconst HEADER = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.\\n// Run \\`codegen entity new --all\\` to refresh.\\n\\n`;\n\nfunction relativeImport(fromFile: string, toFile: string): string {\n\t// Both paths are relative to project root.\n\tconst fromDir = path.posix.dirname(fromFile);\n\tlet rel = path.posix.relative(fromDir, toFile);\n\tif (!rel.startsWith('.')) rel = `./${rel}`;\n\t// Strip .ts extension for TS imports.\n\treturn rel.replace(/\\.ts$/, '');\n}\n\nexport function buildModulesBarrel(\n\tentities: EntityInfo[],\n\tbarrelFile: string,\n\tarchitecture: Architecture,\n\tbackendSrc: string = 'app/backend/src'\n): string {\n\tconst imports: string[] = [];\n\tconst exportsList: string[] = [];\n\n\tfor (const ent of entities) {\n\t\tconst { moduleFile, moduleClass } = entityFilePaths(ent, architecture, backendSrc);\n\t\tconst importPath = relativeImport(barrelFile, moduleFile);\n\t\timports.push(`import { ${moduleClass} } from '${importPath}';`);\n\t\texportsList.push(moduleClass);\n\t}\n\n\tif (entities.length === 0) {\n\t\treturn `${HEADER}export const GENERATED_MODULES = [] as const;\\n`;\n\t}\n\n\tconst body =\n\t\timports.join('\\n') +\n\t\t'\\n\\n' +\n\t\t`export const GENERATED_MODULES = [\\n${exportsList\n\t\t\t.map((n) => `\\t${n},`)\n\t\t\t.join('\\n')}\\n] as const;\\n`;\n\n\treturn HEADER + body;\n}\n\nexport function buildSchemaBarrel(\n\tentities: EntityInfo[],\n\tbarrelFile: string,\n\tarchitecture: Architecture,\n\tbackendSrc: string = 'app/backend/src'\n): string {\n\tif (entities.length === 0) {\n\t\treturn `${HEADER}export {};\\n`;\n\t}\n\n\tconst lines = entities.map((ent) => {\n\t\tconst { schemaFile } = entityFilePaths(ent, architecture, backendSrc);\n\t\treturn `export * from '${relativeImport(barrelFile, schemaFile)}';`;\n\t});\n\n\treturn HEADER + lines.join('\\n') + '\\n';\n}\n\n// ---------------------------------------------------------------------------\n// Public entrypoint\n// ---------------------------------------------------------------------------\n\nexport async function regenerateBarrels(\n\topts: BarrelGeneratorOptions\n): Promise<BarrelResult> {\n\tconst {\n\t\tctx,\n\t\tentitiesDir,\n\t\tgeneratedDir,\n\t\tarchitecture,\n\t\tbackendSrc = resolveBackendSrc(ctx),\n\t\tdryRun = false,\n\t} = opts;\n\tconst cwd = ctx.cwd;\n\n\tconst entities = collectEntities(entitiesDir);\n\n\t// Compute barrel paths relative to project root so imports line up.\n\tconst generatedRel = path.relative(cwd, generatedDir) || path.basename(generatedDir);\n\tconst modulesRel = path.posix.join(\n\t\tgeneratedRel.split(path.sep).join('/'),\n\t\t'modules.ts'\n\t);\n\tconst schemaRel = path.posix.join(\n\t\tgeneratedRel.split(path.sep).join('/'),\n\t\t'schema.ts'\n\t);\n\n\tconst modulesContent = buildModulesBarrel(entities, modulesRel, architecture, backendSrc);\n\tconst schemaContent = buildSchemaBarrel(entities, schemaRel, architecture, backendSrc);\n\n\tconst modulesAbs = path.resolve(cwd, modulesRel);\n\tconst schemaAbs = path.resolve(cwd, schemaRel);\n\n\tlet written = false;\n\tif (!dryRun) {\n\t\tfs.mkdirSync(path.dirname(modulesAbs), { recursive: true });\n\t\tfs.writeFileSync(modulesAbs, modulesContent);\n\t\tfs.writeFileSync(schemaAbs, schemaContent);\n\t\twritten = true;\n\t}\n\n\treturn {\n\t\tmodulesBarrel: modulesAbs,\n\t\tschemaBarrel: schemaAbs,\n\t\tentityCount: entities.length,\n\t\tmodulesContent,\n\t\tschemaContent,\n\t\twritten,\n\t};\n}\n\n/**\n * Resolve the architecture to target from a context's loaded config.\n * Honors `generate.architecture`, falling back to 'clean'.\n */\nexport function resolveArchitecture(ctx: Context): Architecture {\n\tconst cfg = ctx.config as\n\t\t| { generate?: { architecture?: string } }\n\t\t| null\n\t\t| undefined;\n\tconst raw = cfg?.generate?.architecture;\n\treturn raw === 'clean-lite-ps' ? 'clean-lite-ps' : 'clean';\n}\n\n/**\n * Resolve the absolute generated directory from a context.\n * Honors `paths.generated`, falling back to `<cwd>/src/generated`.\n */\nexport function resolveGeneratedDir(ctx: Context): string {\n\tconst fromConfig = (ctx.config as { paths?: { generated?: string } } | null | undefined)\n\t\t?.paths?.generated;\n\tconst rel = typeof fromConfig === 'string' && fromConfig.length > 0\n\t\t? fromConfig\n\t\t: 'src/generated';\n\treturn path.resolve(ctx.cwd, rel);\n}\n\n/**\n * Resolve backend_src from config, defaulting to 'app/backend/src' to match\n * src/config/locations.mjs.\n */\nexport function resolveBackendSrc(ctx: Context): string {\n\tconst fromConfig = (ctx.config as { paths?: { backend_src?: string } } | null | undefined)\n\t\t?.paths?.backend_src;\n\treturn typeof fromConfig === 'string' && fromConfig.length > 0\n\t\t? fromConfig\n\t\t: 'app/backend/src';\n}\n","/**\n * Semantic output helpers. Commands call these rather than reaching into theme/icons.\n *\n * Errors are truncated at 500 chars in interactive output (matching pts behavior).\n * All helpers no-op in JSON mode.\n */\n\nimport { theme } from './theme.js';\nimport { icons } from './icons.js';\nimport { isJsonMode } from './json.js';\n\nconst MAX_ERROR_LEN = 500;\n\nexport function printSuccess(msg: string): void {\n\tif (isJsonMode()) return;\n\tconsole.log(`${theme.success(icons.success)} ${msg}`);\n}\n\nexport function printError(msg: string): void {\n\tif (isJsonMode()) return;\n\tconst truncated = msg.length > MAX_ERROR_LEN ? msg.slice(0, MAX_ERROR_LEN) + '…' : msg;\n\tconsole.error(`${theme.error(icons.error)} ${truncated}`);\n}\n\nexport function printWarning(msg: string): void {\n\tif (isJsonMode()) return;\n\tconsole.warn(`${theme.warning(icons.warning)} ${msg}`);\n}\n\nexport function printInfo(msg: string): void {\n\tif (isJsonMode()) return;\n\tconsole.log(`${theme.system(icons.info)} ${msg}`);\n}\n\nexport function printMuted(msg: string): void {\n\tif (isJsonMode()) return;\n\tconsole.log(theme.muted(msg));\n}\n","/**\n * Entity noun — codegen entity / entity new / entity list / entity validate\n *\n * Implements SPEC-CLI-02. Delegates actual generation to the shared Hygen\n * helper so behavior matches the legacy src/cli.ts.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { Command, Option } from 'clipanion';\nimport type { CommandClass } from 'clipanion';\n\nimport { loadEntityFromYaml } from '../../utils/yaml-loader.js';\nimport { analyzeDomain, validateEntities } from '../../index.js';\n\nimport { loadContext, type Context } from '../shared/context.js';\nimport { invokeEntityNew } from '../shared/hygen.js';\nimport { checkGitSafety } from '../shared/git-safety.js';\nimport {\n\tregenerateBarrels,\n\tresolveArchitecture,\n\tresolveGeneratedDir,\n} from '../shared/barrel-generator.js';\n\nimport { theme } from '../ui/theme.js';\nimport { icons } from '../ui/icons.js';\nimport { printError, printInfo, printSuccess, printWarning } from '../ui/output.js';\nimport { isJsonMode, printJson, setJsonMode } from '../ui/json.js';\nimport type { PaneOutput } from '../ui/pane.js';\nimport type { Hint } from '../ui/hints.js';\nimport type { NounModule } from '../noun-module.js';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction listEntityYamls(dir: string): string[] {\n\tif (!fs.existsSync(dir)) return [];\n\treturn fs\n\t\t.readdirSync(dir)\n\t\t.filter((f) => f.endsWith('.yaml') || f.endsWith('.yml'))\n\t\t.map((f) => path.join(dir, f));\n}\n\ninterface EntitySummaryRow {\n\tname: string;\n\tfamily: string;\n\tfields: number;\n\tqueries: number;\n\tfile: string;\n}\n\nfunction summarizeEntityFile(filePath: string): EntitySummaryRow | null {\n\tconst result = loadEntityFromYaml(filePath);\n\tif (!result.success) return null;\n\tconst def = result.definition;\n\treturn {\n\t\tname: def.entity.name,\n\t\tfamily: (def.entity as { family?: string }).family ?? 'base',\n\t\tfields: Object.keys(def.fields ?? {}).length,\n\t\tqueries: Array.isArray(\n\t\t\t(def as unknown as { queries?: unknown[] }).queries\n\t\t)\n\t\t\t? ((def as unknown as { queries: unknown[] }).queries).length\n\t\t\t: 0,\n\t\tfile: filePath,\n\t};\n}\n\nfunction padRight(s: string, n: number): string {\n\treturn s.length >= n ? s : s + ' '.repeat(n - s.length);\n}\n\n// ---------------------------------------------------------------------------\n// summary + hints\n// ---------------------------------------------------------------------------\n\nasync function summary(ctx: Context): Promise<PaneOutput> {\n\tif (!ctx.entitiesDir || ctx.entityCount === 0) {\n\t\treturn {\n\t\t\ttitle: 'entities',\n\t\t\tbody: [\n\t\t\t\t'No entities defined yet.',\n\t\t\t\t'',\n\t\t\t\t`Create one at ${theme.system('entities/<name>.yaml')} to get started.`,\n\t\t\t],\n\t\t};\n\t}\n\n\tconst files = listEntityYamls(ctx.entitiesDir);\n\tconst rows = files.map(summarizeEntityFile).filter((r): r is EntitySummaryRow => r !== null);\n\n\tconst families = new Set(rows.map((r) => r.family));\n\tconst queryCount = rows.reduce((sum, r) => sum + r.queries, 0);\n\n\tconst nameCol = Math.max(4, ...rows.map((r) => r.name.length));\n\tconst famCol = Math.max(6, ...rows.map((r) => r.family.length));\n\n\tconst body = rows.map((r) => {\n\t\tconst fields = `${r.fields} fields`.padEnd(10);\n\t\tconst queries = `${r.queries} queries`.padEnd(10);\n\t\treturn `${theme.system(icons.bullet)} ${padRight(r.name, nameCol)} ${theme.muted(\n\t\t\tpadRight(r.family, famCol)\n\t\t)} ${theme.muted(fields)} ${theme.muted(queries)}`;\n\t});\n\n\treturn {\n\t\ttitle: 'entities',\n\t\tbody,\n\t\tfooter: `${rows.length} entities · ${families.size} families · ${queryCount} queries`,\n\t};\n}\n\nasync function hints(ctx: Context): Promise<Hint[]> {\n\tif (!ctx.isInitialized) {\n\t\treturn [{ command: 'codegen init', description: 'Initialize project' }];\n\t}\n\tif (!ctx.entitiesDir || ctx.entityCount === 0) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tcommand: 'codegen entity new entities/example.yaml',\n\t\t\t\tdescription: 'Generate first entity',\n\t\t\t},\n\t\t];\n\t}\n\treturn [\n\t\t{ command: 'codegen entity new <file>', description: 'Generate one entity' },\n\t\t{ command: 'codegen entity new --all', description: 'Regenerate all entities' },\n\t\t{ command: 'codegen entity validate', description: 'Validate YAML definitions' },\n\t\t{ command: 'codegen entity list', description: 'List entities as a table' },\n\t];\n}\n\n// ---------------------------------------------------------------------------\n// EntityNewCommand\n// ---------------------------------------------------------------------------\n\nexport class EntityNewCommand extends Command {\n\tstatic paths = [['entity', 'new']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'Generate code for one or more entities from YAML',\n\t\texamples: [\n\t\t\t['Generate a single entity', 'codegen entity new entities/contact.yaml'],\n\t\t\t['Regenerate all entities', 'codegen entity new --all'],\n\t\t\t['Preview without writing', 'codegen entity new entities/contact.yaml --dry-run'],\n\t\t],\n\t});\n\n\tyaml = Option.String({ required: false });\n\tall = Option.Boolean('--all', false);\n\tdryRun = Option.Boolean('--dry-run', false);\n\tforce = Option.Boolean('--force', false);\n\tonly = Option.String('--only', { required: false });\n\tcontinueOnError = Option.Boolean('--continue-on-error', false);\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json) setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tconfigPath: this.configPath,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: true,\n\t\t});\n\n\t\tif (this.all && this.yaml) {\n\t\t\tprintError('Pass either a YAML path or --all, not both.');\n\t\t\treturn 2;\n\t\t}\n\n\t\tlet targets: string[] = [];\n\t\tif (this.all) {\n\t\t\tconst dir = ctx.entitiesDir ?? path.resolve(ctx.cwd, 'entities');\n\t\t\ttargets = listEntityYamls(dir);\n\t\t\tif (targets.length === 0) {\n\t\t\t\tprintError(`No entity YAML files found in ${dir}`);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t} else if (this.yaml) {\n\t\t\ttargets = [path.resolve(ctx.cwd, this.yaml)];\n\t\t} else {\n\t\t\tprintError('Missing YAML path. Pass a file or --all.');\n\t\t\treturn 2;\n\t\t}\n\n\t\t// Pre-flight: validate each YAML.\n\t\tconst validated: Array<{ file: string; name: string }> = [];\n\t\tconst invalid: Array<{ file: string; message: string }> = [];\n\t\tfor (const file of targets) {\n\t\t\tconst result = loadEntityFromYaml(file);\n\t\t\tif (result.success) {\n\t\t\t\tvalidated.push({ file, name: result.definition.entity.name });\n\t\t\t} else {\n\t\t\t\tinvalid.push({ file, message: result.error });\n\t\t\t}\n\t\t}\n\n\t\tif (invalid.length > 0 && !this.continueOnError) {\n\t\t\tfor (const i of invalid) {\n\t\t\t\tprintError(`${path.basename(i.file)} — ${i.message}`);\n\t\t\t}\n\t\t\tif (!isJsonMode()) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\t// Git safety — we don't know specific output paths without running Hygen,\n\t\t// so scope the check to the cwd's generated source roots if we can.\n\t\tif (!this.force) {\n\t\t\tconst gitCheck = checkGitSafety(['src'], ctx.cwd);\n\t\t\tif (gitCheck.inRepo && !gitCheck.clean) {\n\t\t\t\tprintWarning(\n\t\t\t\t\t`Uncommitted changes in ${gitCheck.dirty.length} files under src/. Pass --force to overwrite.`\n\t\t\t\t);\n\t\t\t\tif (!isJsonMode()) return 1;\n\t\t\t}\n\t\t}\n\n\t\t// Compute barrel plan (used in both dry-run reporting and post-gen execution).\n\t\tconst entitiesDir = ctx.entitiesDir ?? path.resolve(ctx.cwd, 'entities');\n\t\tconst generatedDir = resolveGeneratedDir(ctx);\n\t\tconst architecture = resolveArchitecture(ctx);\n\n\t\tif (this.dryRun) {\n\t\t\tconst barrelPlan = await regenerateBarrels({\n\t\t\t\tctx,\n\t\t\t\tentitiesDir,\n\t\t\t\tgeneratedDir,\n\t\t\t\tarchitecture,\n\t\t\t\tdryRun: true,\n\t\t\t});\n\n\t\t\tif (isJsonMode()) {\n\t\t\t\tprintJson({\n\t\t\t\t\tcommand: 'entity new',\n\t\t\t\t\tdryRun: true,\n\t\t\t\t\tentities: validated.map((v) => ({ name: v.name, file: v.file })),\n\t\t\t\t\ttotals: { planned: validated.length, invalid: invalid.length },\n\t\t\t\t\tbarrels: {\n\t\t\t\t\t\tmodules: barrelPlan.modulesBarrel,\n\t\t\t\t\t\tschema: barrelPlan.schemaBarrel,\n\t\t\t\t\t\tentityCount: barrelPlan.entityCount,\n\t\t\t\t\t\tmodulesContent: barrelPlan.modulesContent,\n\t\t\t\t\t\tschemaContent: barrelPlan.schemaContent,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tprintInfo(`Dry run — ${validated.length} entities would be generated:`);\n\t\t\t\tfor (const v of validated) {\n\t\t\t\t\tconsole.log(` ${theme.muted(icons.arrow)} ${v.name} ${theme.muted(v.file)}`);\n\t\t\t\t}\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tfor (const i of invalid) {\n\t\t\t\t\t\tprintWarning(`${path.basename(i.file)} — ${i.message}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconsole.log('');\n\t\t\t\tprintInfo(`Barrels (${barrelPlan.entityCount} entities):`);\n\t\t\t\tconsole.log(` ${theme.muted(icons.arrow)} ${barrelPlan.modulesBarrel}`);\n\t\t\t\tconsole.log(` ${theme.muted(icons.arrow)} ${barrelPlan.schemaBarrel}`);\n\t\t\t}\n\t\t\treturn invalid.length > 0 && !this.continueOnError ? 1 : 0;\n\t\t}\n\n\t\t// Invoke Hygen for each validated target.\n\t\tconst succeeded: string[] = [];\n\t\tconst failed: Array<{ name: string; file: string; message: string }> = [\n\t\t\t...invalid.map((i) => ({ name: path.basename(i.file), file: i.file, message: i.message })),\n\t\t];\n\t\tfor (const v of validated) {\n\t\t\tif (!isJsonMode()) {\n\t\t\t\tprintInfo(`generating ${v.name}`);\n\t\t\t}\n\t\t\tconst res = invokeEntityNew(v.file, ctx.cwd);\n\t\t\tif (res.ok) {\n\t\t\t\tsucceeded.push(v.name);\n\t\t\t\tif (!isJsonMode()) printSuccess(`${v.name}`);\n\t\t\t} else {\n\t\t\t\tfailed.push({\n\t\t\t\t\tname: v.name,\n\t\t\t\t\tfile: v.file,\n\t\t\t\t\tmessage: res.stderr ?? 'Hygen invocation failed',\n\t\t\t\t});\n\t\t\t\tif (!isJsonMode()) printError(`${v.name} — ${res.stderr ?? 'failed'}`);\n\t\t\t\tif (!this.continueOnError) break;\n\t\t\t}\n\t\t}\n\n\t\t// Regenerate barrels once, after all Hygen invocations. This is total —\n\t\t// every .yaml in entitiesDir is re-scanned, so deleting an entity YAML and\n\t\t// re-running removes it from the barrels. See ADR-017.\n\t\tlet barrelResult: Awaited<ReturnType<typeof regenerateBarrels>> | null = null;\n\t\ttry {\n\t\t\tbarrelResult = await regenerateBarrels({\n\t\t\t\tctx,\n\t\t\t\tentitiesDir,\n\t\t\t\tgeneratedDir,\n\t\t\t\tarchitecture,\n\t\t\t});\n\t\t} catch (err: unknown) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\tif (!isJsonMode()) {\n\t\t\t\tprintWarning(`barrel regeneration failed — ${msg}`);\n\t\t\t}\n\t\t}\n\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({\n\t\t\t\tcommand: 'entity new',\n\t\t\t\ttotals: {\n\t\t\t\t\tsucceeded: succeeded.length,\n\t\t\t\t\tfailed: failed.length,\n\t\t\t\t},\n\t\t\t\tsucceeded,\n\t\t\t\tfailed,\n\t\t\t\tbarrels: barrelResult\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tmodules: barrelResult.modulesBarrel,\n\t\t\t\t\t\t\tschema: barrelResult.schemaBarrel,\n\t\t\t\t\t\t\tentityCount: barrelResult.entityCount,\n\t\t\t\t\t\t}\n\t\t\t\t\t: null,\n\t\t\t});\n\t\t} else {\n\t\t\tconst total = validated.length + invalid.length;\n\t\t\tconsole.log('');\n\t\t\tif (failed.length === 0) {\n\t\t\t\tprintSuccess(`${total} entities · ${succeeded.length} succeeded`);\n\t\t\t} else {\n\t\t\t\tprintWarning(\n\t\t\t\t\t`${total} entities · ${succeeded.length} succeeded · ${failed.length} failed`\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (barrelResult) {\n\t\t\t\tprintInfo(\n\t\t\t\t\t`barrels regenerated (${barrelResult.entityCount} entities) → ${path.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path.relative(ctx.cwd, barrelResult.schemaBarrel)}`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn failed.length === 0 ? 0 : 1;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// EntityListCommand\n// ---------------------------------------------------------------------------\n\nexport class EntityListCommand extends Command {\n\tstatic paths = [['entity', 'list']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'List defined entities as a table',\n\t});\n\n\tfamily = Option.String('--family', { required: false });\n\tformat = Option.String('--format', 'plain');\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json || this.format === 'json') setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tconfigPath: this.configPath,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: true,\n\t\t});\n\n\t\tif (!ctx.entitiesDir) {\n\t\t\tprintError('No entities directory found.');\n\t\t\treturn 1;\n\t\t}\n\n\t\tconst files = listEntityYamls(ctx.entitiesDir);\n\t\tconst rows = files\n\t\t\t.map(summarizeEntityFile)\n\t\t\t.filter((r): r is EntitySummaryRow => r !== null)\n\t\t\t.filter((r) => (this.family ? r.family === this.family : true));\n\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({\n\t\t\t\tcommand: 'entity list',\n\t\t\t\tentities: rows,\n\t\t\t});\n\t\t\treturn 0;\n\t\t}\n\n\t\tif (this.format === 'tree') {\n\t\t\tconst byFamily = new Map<string, EntitySummaryRow[]>();\n\t\t\tfor (const r of rows) {\n\t\t\t\tconst list = byFamily.get(r.family) ?? [];\n\t\t\t\tlist.push(r);\n\t\t\t\tbyFamily.set(r.family, list);\n\t\t\t}\n\t\t\tfor (const [fam, list] of byFamily) {\n\t\t\t\tconsole.log(theme.system(fam));\n\t\t\t\tfor (const r of list) {\n\t\t\t\t\tconsole.log(` ${theme.muted(icons.bullet)} ${r.name} ${theme.muted(`${r.fields} fields`)}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\n\t\t// plain\n\t\tconst nameW = Math.max(4, ...rows.map((r) => r.name.length));\n\t\tconst famW = Math.max(6, ...rows.map((r) => r.family.length));\n\t\tconsole.log(\n\t\t\ttheme.muted(\n\t\t\t\t`${padRight('NAME', nameW)} ${padRight('FAMILY', famW)} ${padRight('FIELDS', 8)} ${padRight('QUERIES', 8)}`\n\t\t\t)\n\t\t);\n\t\tfor (const r of rows) {\n\t\t\tconsole.log(\n\t\t\t\t`${padRight(r.name, nameW)} ${padRight(r.family, famW)} ${padRight(String(r.fields), 8)} ${padRight(String(r.queries), 8)}`\n\t\t\t);\n\t\t}\n\t\treturn 0;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// EntityValidateCommand\n// ---------------------------------------------------------------------------\n\nexport class EntityValidateCommand extends Command {\n\tstatic paths = [['entity', 'validate']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'Validate entity YAML definitions against the schema',\n\t});\n\n\tdir = Option.String({ required: false });\n\tstrict = Option.Boolean('--strict', false);\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json) setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tconfigPath: this.configPath,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: true,\n\t\t});\n\n\t\tconst targetDir = this.dir\n\t\t\t? path.resolve(ctx.cwd, this.dir)\n\t\t\t: ctx.entitiesDir ?? path.resolve(ctx.cwd, 'entities');\n\n\t\tif (!fs.existsSync(targetDir)) {\n\t\t\tprintError(`Directory not found: ${targetDir}`);\n\t\t\treturn 1;\n\t\t}\n\n\t\tconst quick = validateEntities(targetDir);\n\t\tconst full = await analyzeDomain(targetDir);\n\n\t\tconst errors = full.issues.filter((i) => i.severity === 'error');\n\t\tconst warnings = full.issues.filter((i) => i.severity === 'warning');\n\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({\n\t\t\t\tcommand: 'entity validate',\n\t\t\t\tdirectory: targetDir,\n\t\t\t\tvalid: quick.valid && errors.length === 0,\n\t\t\t\terrors: errors.map((e) => ({ entity: e.entity, path: e.path, message: e.message })),\n\t\t\t\twarnings: warnings.map((w) => ({\n\t\t\t\t\tentity: w.entity,\n\t\t\t\t\tpath: w.path,\n\t\t\t\t\tmessage: w.message,\n\t\t\t\t})),\n\t\t\t});\n\t\t\tif (errors.length > 0) return 1;\n\t\t\tif (this.strict && warnings.length > 0) return 1;\n\t\t\treturn 0;\n\t\t}\n\n\t\tif (errors.length === 0) {\n\t\t\tprintSuccess(`All entities validated — ${full.entities.length} checked`);\n\t\t} else {\n\t\t\tprintError(`${errors.length} validation errors`);\n\t\t\tfor (const e of errors) {\n\t\t\t\tconsole.log(` ${theme.error(icons.error)} ${e.entity ?? e.path ?? ''}: ${e.message}`);\n\t\t\t}\n\t\t}\n\t\tif (warnings.length > 0) {\n\t\t\tfor (const w of warnings) {\n\t\t\t\tprintWarning(`${w.entity ?? w.path ?? ''}: ${w.message}`);\n\t\t\t}\n\t\t}\n\n\t\tif (errors.length > 0) return 1;\n\t\tif (this.strict && warnings.length > 0) return 1;\n\t\treturn 0;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// NounModule default export\n// ---------------------------------------------------------------------------\n\nconst entityNoun: NounModule = {\n\tname: 'entity',\n\tcommandClasses: [EntityNewCommand, EntityListCommand, EntityValidateCommand] as CommandClass[],\n\tsummary,\n\thints,\n};\n\nexport default entityNoun;\n","/**\n * runtime-copier — copy a runtime/ subdirectory into a user's project.\n *\n * Used by the subsystem noun to install {events, jobs, cache, storage} from\n * the shipped `runtime/subsystems/<name>/` into the user's project. Honors\n * file filters (for backend selection) and optionally walks the import graph\n * to also copy referenced runtime/types/ and runtime/constants/ files.\n *\n * The runtime tree is treated as read-only source of truth; this module only\n * reads from it and writes into the user's target.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nexport interface RuntimeCopyOptions {\n\tsourceDir: string;\n\ttargetDir: string;\n\tfilter?: (file: string) => boolean;\n\tresolveDeps?: boolean;\n\t/** runtime/ root (parent of subsystems/, types/, constants/). */\n\truntimeRoot?: string;\n\t/** Where dependency files like runtime/types/foo.ts should land in the user project.\n\t * Defaults to the parent directory of targetDir. */\n\tdepsTargetRoot?: string;\n\tdryRun?: boolean;\n}\n\nexport interface RuntimeCopyResult {\n\twritten: string[];\n\tupdated: string[];\n\tunchanged: string[];\n\tdependenciesCopied: string[];\n\tplanned: string[];\n}\n\nfunction readIfExists(p: string): string | null {\n\ttry {\n\t\treturn fs.readFileSync(p, 'utf-8');\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction writeFile(target: string, content: string): 'written' | 'updated' | 'unchanged' {\n\tconst existing = readIfExists(target);\n\tif (existing === content) return 'unchanged';\n\tfs.mkdirSync(path.dirname(target), { recursive: true });\n\tfs.writeFileSync(target, content);\n\treturn existing === null ? 'written' : 'updated';\n}\n\n/**\n * Extract relative import paths from a TypeScript source file. Returns the\n * raw specifiers (e.g. '../../types/drizzle').\n */\nfunction extractRelativeImports(source: string): string[] {\n\tconst out: string[] = [];\n\tconst re =\n\t\t/(?:import|export)\\s+(?:[^'\"`;]*?\\s+from\\s+)?['\"`](\\.{1,2}\\/[^'\"`]+)['\"`]/g;\n\tlet m: RegExpExecArray | null;\n\twhile ((m = re.exec(source)) !== null) {\n\t\tout.push(m[1]);\n\t}\n\treturn out;\n}\n\nfunction resolveSourceImport(\n\tsourceFile: string,\n\tspecifier: string\n): string | null {\n\tconst base = path.resolve(path.dirname(sourceFile), specifier);\n\tconst candidates = [base + '.ts', base + '.tsx', path.join(base, 'index.ts')];\n\tfor (const c of candidates) {\n\t\tif (fs.existsSync(c)) return c;\n\t}\n\treturn null;\n}\n\n/**\n * Copy `sourceDir` into `targetDir`. Optionally follows relative imports and\n * copies referenced runtime/types/* and runtime/constants/* into a sibling\n * directory structure of targetDir.\n */\nexport async function copyRuntime(opts: RuntimeCopyOptions): Promise<RuntimeCopyResult> {\n\tconst { sourceDir, targetDir, filter, resolveDeps, dryRun } = opts;\n\n\tif (!fs.existsSync(sourceDir) || !fs.statSync(sourceDir).isDirectory()) {\n\t\tthrow new Error(`runtime source directory not found: ${sourceDir}`);\n\t}\n\n\tconst runtimeRoot = opts.runtimeRoot\n\t\t? path.resolve(opts.runtimeRoot)\n\t\t: path.resolve(sourceDir, '..', '..'); // runtime/subsystems/<x> → runtime/\n\tconst depsTargetRoot = opts.depsTargetRoot ?? path.resolve(targetDir, '..');\n\n\tconst result: RuntimeCopyResult = {\n\t\twritten: [],\n\t\tupdated: [],\n\t\tunchanged: [],\n\t\tdependenciesCopied: [],\n\t\tplanned: [],\n\t};\n\n\t// Queue of source paths to copy; value is the destination path.\n\tconst queue: Array<{ src: string; dest: string; isDep: boolean }> = [];\n\n\t// Enumerate files in sourceDir\n\tconst entries = fs.readdirSync(sourceDir);\n\tfor (const entry of entries) {\n\t\tconst src = path.join(sourceDir, entry);\n\t\tconst stat = fs.statSync(src);\n\t\tif (!stat.isFile()) continue;\n\t\tif (!entry.endsWith('.ts') && !entry.endsWith('.tsx')) continue;\n\t\tif (filter && !filter(entry)) continue;\n\t\tqueue.push({ src, dest: path.join(targetDir, entry), isDep: false });\n\t}\n\n\tconst visited = new Set<string>();\n\n\twhile (queue.length > 0) {\n\t\tconst next = queue.shift()!;\n\t\tif (visited.has(next.src)) continue;\n\t\tvisited.add(next.src);\n\n\t\tconst content = fs.readFileSync(next.src, 'utf-8');\n\t\tresult.planned.push(next.dest);\n\n\t\tif (!dryRun) {\n\t\t\tconst status = writeFile(next.dest, content);\n\t\t\tif (status === 'written') result.written.push(next.dest);\n\t\t\telse if (status === 'updated') result.updated.push(next.dest);\n\t\t\telse result.unchanged.push(next.dest);\n\t\t\tif (next.isDep) result.dependenciesCopied.push(next.dest);\n\t\t}\n\n\t\tif (resolveDeps) {\n\t\t\tfor (const spec of extractRelativeImports(content)) {\n\t\t\t\tconst resolvedSrc = resolveSourceImport(next.src, spec);\n\t\t\t\tif (!resolvedSrc) continue;\n\t\t\t\t// Only follow imports that land inside runtimeRoot.\n\t\t\t\tconst relToRuntime = path.relative(runtimeRoot, resolvedSrc);\n\t\t\t\tif (relToRuntime.startsWith('..') || path.isAbsolute(relToRuntime)) continue;\n\t\t\t\t// If already under sourceDir, it's local — copied by the main loop already.\n\t\t\t\tconst relToSource = path.relative(sourceDir, resolvedSrc);\n\t\t\t\tif (!relToSource.startsWith('..') && !path.isAbsolute(relToSource)) continue;\n\n\t\t\t\t// Place it under depsTargetRoot at the same relative path from runtimeRoot\n\t\t\t\t// minus the leading 'subsystems/<name>' if the file lives elsewhere.\n\t\t\t\t// Simpler: preserve runtime's own relative structure under depsTargetRoot.\n\t\t\t\tconst depDest = path.join(depsTargetRoot, relToRuntime);\n\t\t\t\tqueue.push({ src: resolvedSrc, dest: depDest, isDep: true });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n","/**\n * Detect which subsystems (events/jobs/cache/storage) are already installed\n * in the user's project. A subsystem is \"installed\" when a `<name>.protocol.ts`\n * exists under a known install root.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { Context } from './context.js';\n\nexport type SubsystemName = 'events' | 'jobs' | 'cache' | 'storage';\nexport type SubsystemBackend = 'drizzle' | 'memory' | 'local' | 'unknown';\n\nexport interface InstalledSubsystem {\n\tname: SubsystemName;\n\tpath: string;\n\tbackend: SubsystemBackend;\n}\n\nexport interface SubsystemDescriptor {\n\tname: SubsystemName;\n\tdescription: string;\n\tbackends: SubsystemBackend[];\n\tdefaultBackend: SubsystemBackend;\n}\n\nexport const SUBSYSTEMS: SubsystemDescriptor[] = [\n\t{\n\t\tname: 'events',\n\t\tdescription: 'Domain event bus (transactional outbox)',\n\t\tbackends: ['drizzle', 'memory'],\n\t\tdefaultBackend: 'drizzle',\n\t},\n\t{\n\t\tname: 'jobs',\n\t\tdescription: 'Background job queue',\n\t\tbackends: ['drizzle', 'memory'],\n\t\tdefaultBackend: 'drizzle',\n\t},\n\t{\n\t\tname: 'cache',\n\t\tdescription: 'Key-value cache with TTL',\n\t\tbackends: ['drizzle', 'memory'],\n\t\tdefaultBackend: 'drizzle',\n\t},\n\t{\n\t\tname: 'storage',\n\t\tdescription: 'File/object storage',\n\t\tbackends: ['local', 'memory'],\n\t\tdefaultBackend: 'local',\n\t},\n];\n\nconst KNOWN_NAMES = SUBSYSTEMS.map((s) => s.name);\n\nfunction candidateRoots(cwd: string, configured?: string): string[] {\n\tconst roots = [\n\t\t...(configured ? [path.resolve(cwd, configured)] : []),\n\t\tpath.resolve(cwd, 'src/shared/subsystems'),\n\t\tpath.resolve(cwd, 'src/subsystems'),\n\t\tpath.resolve(cwd, 'shared/subsystems'),\n\t];\n\t// Deduplicate while preserving order\n\treturn Array.from(new Set(roots));\n}\n\nfunction inferBackend(dir: string, name: SubsystemName): SubsystemBackend {\n\tconst hasDrizzle = fs.existsSync(path.join(dir, `${name.replace(/s$/, '')}-bus.drizzle-backend.ts`))\n\t\t|| fs.readdirSync(dir).some((f) => f.endsWith('.drizzle-backend.ts'));\n\tconst hasMemory = fs.readdirSync(dir).some((f) => f.endsWith('.memory-backend.ts'));\n\tconst hasLocal = fs.readdirSync(dir).some((f) => f.includes('local'));\n\tif (hasDrizzle && hasMemory) return 'drizzle'; // both present → drizzle is the active one\n\tif (hasDrizzle) return 'drizzle';\n\tif (hasLocal) return 'local';\n\tif (hasMemory) return 'memory';\n\treturn 'unknown';\n}\n\nexport async function detectInstalledSubsystems(ctx: Context): Promise<InstalledSubsystem[]> {\n\tconst configured = ctx.config?.paths?.subsystems as string | undefined;\n\tconst roots = candidateRoots(ctx.cwd, configured);\n\n\tconst found: InstalledSubsystem[] = [];\n\tconst seen = new Set<SubsystemName>();\n\n\tfor (const root of roots) {\n\t\tif (!fs.existsSync(root)) continue;\n\t\tfor (const name of KNOWN_NAMES) {\n\t\t\tif (seen.has(name)) continue;\n\t\t\tconst dir = path.join(root, name);\n\t\t\tif (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) continue;\n\t\t\t// A subsystem is installed when the directory contains any *.protocol.ts\n\t\t\tconst files = fs.readdirSync(dir);\n\t\t\tconst hasProtocol = files.some((f) => f.endsWith('.protocol.ts'));\n\t\t\tif (!hasProtocol) continue;\n\t\t\tseen.add(name);\n\t\t\tfound.push({\n\t\t\t\tname,\n\t\t\t\tpath: dir,\n\t\t\t\tbackend: inferBackend(dir, name),\n\t\t\t});\n\t\t}\n\t}\n\n\treturn found;\n}\n","/**\n * Subsystem noun — install / list / remove (stub).\n *\n * Implements SPEC-CLI-03. Installs runtime subsystems (events/jobs/cache/\n * storage) into a user's project by copying `runtime/subsystems/<name>/`\n * plus any referenced runtime dependencies (types, constants).\n *\n * The `runtime/` directory is shipped-read-only; this command only reads it.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { Command, Option } from 'clipanion';\nimport type { CommandClass } from 'clipanion';\n\nimport { loadContext, type Context } from '../shared/context.js';\nimport { checkGitSafety } from '../shared/git-safety.js';\nimport { copyRuntime } from '../shared/runtime-copier.js';\nimport {\n\tSUBSYSTEMS,\n\tdetectInstalledSubsystems,\n\ttype SubsystemDescriptor,\n\ttype SubsystemName,\n\ttype SubsystemBackend,\n\ttype InstalledSubsystem,\n} from '../shared/subsystem-detect.js';\n\nimport { theme } from '../ui/theme.js';\nimport { icons } from '../ui/icons.js';\nimport { printError, printInfo, printSuccess, printWarning } from '../ui/output.js';\nimport { isJsonMode, printJson, setJsonMode } from '../ui/json.js';\nimport type { PaneOutput } from '../ui/pane.js';\nimport type { Hint } from '../ui/hints.js';\nimport type { NounModule } from '../noun-module.js';\n\n// ---------------------------------------------------------------------------\n// paths\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_SUBSYSTEMS_REL = 'shared/subsystems';\n\nfunction runtimeRoot(): string {\n\t// src/cli/commands/subsystem.ts → ../../../runtime\n\treturn path.resolve(import.meta.dirname, '..', '..', '..', 'runtime');\n}\n\nfunction subsystemSource(name: SubsystemName): string {\n\treturn path.join(runtimeRoot(), 'subsystems', name);\n}\n\nfunction resolveTargetRoot(ctx: Context, overrideTarget?: string): string {\n\tif (overrideTarget) return path.resolve(ctx.cwd, overrideTarget);\n\tconst configured = ctx.config?.paths?.subsystems as string | undefined;\n\tif (configured) return path.resolve(ctx.cwd, configured);\n\treturn path.resolve(ctx.cwd, DEFAULT_SUBSYSTEMS_REL);\n}\n\nfunction describeSubsystem(name: string): SubsystemDescriptor | null {\n\treturn SUBSYSTEMS.find((s) => s.name === name) ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// summary + hints\n// ---------------------------------------------------------------------------\n\nasync function summary(ctx: Context): Promise<PaneOutput> {\n\tconst installed = await detectInstalledSubsystems(ctx);\n\tconst installedNames = new Set(installed.map((i) => i.name));\n\tconst missing = SUBSYSTEMS.filter((s) => !installedNames.has(s.name));\n\n\tconst body: string[] = [];\n\n\tif (installed.length === 0) {\n\t\tbody.push(theme.muted('Available:'));\n\t\tfor (const s of SUBSYSTEMS) {\n\t\t\tbody.push(\n\t\t\t\t` ${theme.muted(icons.dash)} ${s.name.padEnd(10)} ${theme.muted(s.description)}`\n\t\t\t);\n\t\t}\n\t\tbody.push('');\n\t\tbody.push(theme.muted('No subsystems installed yet.'));\n\t\treturn {\n\t\t\ttitle: 'subsystems',\n\t\t\tbody,\n\t\t\tfooter: `0 of ${SUBSYSTEMS.length} subsystems installed`,\n\t\t};\n\t}\n\n\tbody.push(theme.muted('Installed:'));\n\tfor (const i of installed) {\n\t\tconst rel = path.relative(ctx.cwd, i.path) || i.path;\n\t\tbody.push(\n\t\t\t` ${theme.success(icons.check)} ${i.name.padEnd(10)} ${theme.muted(\n\t\t\t\t`${i.backend} backend`\n\t\t\t)} ${theme.muted(rel)}`\n\t\t);\n\t}\n\n\tif (missing.length > 0) {\n\t\tbody.push('');\n\t\tbody.push(theme.muted('Available:'));\n\t\tfor (const s of missing) {\n\t\t\tbody.push(\n\t\t\t\t` ${theme.muted(icons.dash)} ${s.name.padEnd(10)} ${theme.muted('not installed')}`\n\t\t\t);\n\t\t}\n\t}\n\n\treturn {\n\t\ttitle: 'subsystems',\n\t\tbody,\n\t\tfooter: `${installed.length} of ${SUBSYSTEMS.length} subsystems installed`,\n\t};\n}\n\nasync function hints(ctx: Context): Promise<Hint[]> {\n\tif (!ctx.isInitialized) {\n\t\treturn [{ command: 'codegen init', description: 'Initialize project' }];\n\t}\n\tconst installed = await detectInstalledSubsystems(ctx);\n\tconst installedNames = new Set(installed.map((i) => i.name));\n\tconst missing = SUBSYSTEMS.filter((s) => !installedNames.has(s.name));\n\n\tif (missing.length === 0) {\n\t\treturn [{ command: 'codegen subsystem list', description: 'List installed subsystems' }];\n\t}\n\n\tconst out: Hint[] = [];\n\tfor (const s of missing.slice(0, 3)) {\n\t\tout.push({\n\t\t\tcommand: `codegen subsystem install ${s.name}`,\n\t\t\tdescription: `Install the ${s.name} subsystem`,\n\t\t});\n\t}\n\treturn out;\n}\n\n// ---------------------------------------------------------------------------\n// SubsystemInstallCommand\n// ---------------------------------------------------------------------------\n\nfunction isValidBackend(\n\tname: SubsystemName,\n\tbackend: string\n): backend is SubsystemBackend {\n\tconst desc = describeSubsystem(name);\n\tif (!desc) return false;\n\treturn (desc.backends as string[]).includes(backend);\n}\n\nfunction backendFileFilter(backend: SubsystemBackend): (file: string) => boolean {\n\treturn (file: string) => {\n\t\tif (backend === 'memory') {\n\t\t\tif (file.endsWith('.drizzle-backend.ts')) return false;\n\t\t\tif (file.endsWith('.schema.ts')) return false;\n\t\t\treturn true;\n\t\t}\n\t\t// drizzle, local, or unknown — copy everything (memory backend is always\n\t\t// needed for tests, even when drizzle is the default runtime backend)\n\t\treturn true;\n\t};\n}\n\nexport class SubsystemInstallCommand extends Command {\n\tstatic paths = [['subsystem', 'install']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'Install a runtime subsystem into the project',\n\t\texamples: [\n\t\t\t['Install the events subsystem', 'codegen subsystem install events'],\n\t\t\t['Install jobs with memory backend', 'codegen subsystem install jobs --backend memory'],\n\t\t\t['Preview without writing', 'codegen subsystem install cache --dry-run'],\n\t\t],\n\t});\n\n\tname = Option.String({ required: true });\n\tbackend = Option.String('--backend', { required: false });\n\ttarget = Option.String('--target', { required: false });\n\tforce = Option.Boolean('--force', false);\n\tyes = Option.Boolean('--yes,-y', false);\n\tdryRun = Option.Boolean('--dry-run', false);\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json) setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tconfigPath: this.configPath,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: true,\n\t\t});\n\n\t\tconst desc = describeSubsystem(this.name);\n\t\tif (!desc) {\n\t\t\tprintError(\n\t\t\t\t`Unknown subsystem '${this.name}'. Known: ${SUBSYSTEMS.map((s) => s.name).join(', ')}`\n\t\t\t);\n\t\t\treturn 2;\n\t\t}\n\n\t\tconst backend = (this.backend ?? desc.defaultBackend) as SubsystemBackend;\n\t\tif (this.backend && !isValidBackend(desc.name, this.backend)) {\n\t\t\tprintError(\n\t\t\t\t`Backend '${this.backend}' not supported for '${desc.name}'. Valid: ${desc.backends.join(\n\t\t\t\t\t', '\n\t\t\t\t)}`\n\t\t\t);\n\t\t\treturn 2;\n\t\t}\n\n\t\tconst installed = await detectInstalledSubsystems(ctx);\n\t\tconst already = installed.find((i) => i.name === desc.name);\n\t\tif (already && !this.force) {\n\t\t\tif (isJsonMode()) {\n\t\t\t\tprintJson({\n\t\t\t\t\tcommand: 'subsystem install',\n\t\t\t\t\tsubsystem: desc.name,\n\t\t\t\t\tstatus: 'already-installed',\n\t\t\t\t\tpath: already.path,\n\t\t\t\t\tbackend: already.backend,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tprintInfo(`${desc.name} is already installed at ${already.path} (pass --force to reinstall)`);\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\n\t\tconst targetRoot = resolveTargetRoot(ctx, this.target);\n\t\tconst subsystemTarget = path.join(targetRoot, desc.name);\n\t\tconst source = subsystemSource(desc.name);\n\n\t\tif (!fs.existsSync(source)) {\n\t\t\tprintError(`Runtime subsystem source missing: ${source}`);\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (!this.force) {\n\t\t\tconst gitCheck = checkGitSafety([path.relative(ctx.cwd, subsystemTarget) || subsystemTarget], ctx.cwd);\n\t\t\tif (gitCheck.inRepo && !gitCheck.clean) {\n\t\t\t\tprintWarning(\n\t\t\t\t\t`Uncommitted changes under ${subsystemTarget}. Pass --force to overwrite.`\n\t\t\t\t);\n\t\t\t\tif (!isJsonMode()) return 1;\n\t\t\t}\n\t\t}\n\n\t\tif (!isJsonMode()) {\n\t\t\tprintInfo(`target = ${path.relative(ctx.cwd, subsystemTarget) || subsystemTarget}`);\n\t\t\tprintInfo(`backend = ${backend}`);\n\t\t}\n\n\t\tconst result = await copyRuntime({\n\t\t\tsourceDir: source,\n\t\t\ttargetDir: subsystemTarget,\n\t\t\tfilter: backendFileFilter(backend),\n\t\t\tresolveDeps: true,\n\t\t\truntimeRoot: runtimeRoot(),\n\t\t\tdepsTargetRoot: path.resolve(targetRoot, '..'),\n\t\t\tdryRun: this.dryRun,\n\t\t});\n\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({\n\t\t\t\tcommand: 'subsystem install',\n\t\t\t\tsubsystem: desc.name,\n\t\t\t\tbackend,\n\t\t\t\ttarget: subsystemTarget,\n\t\t\t\tdryRun: this.dryRun,\n\t\t\t\tfiles: {\n\t\t\t\t\twritten: result.written,\n\t\t\t\t\tupdated: result.updated,\n\t\t\t\t\tunchanged: result.unchanged,\n\t\t\t\t\tplanned: result.planned,\n\t\t\t\t\tdependencies: result.dependenciesCopied,\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn 0;\n\t\t}\n\n\t\tif (this.dryRun) {\n\t\t\tprintInfo(`Dry run — ${result.planned.length} files would be written`);\n\t\t\tfor (const p of result.planned) {\n\t\t\t\tconsole.log(` ${theme.muted(icons.arrow)} ${path.relative(ctx.cwd, p) || p}`);\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\n\t\tconst total = result.written.length + result.updated.length + result.unchanged.length;\n\t\tprintSuccess(\n\t\t\t`copied ${total} files (${result.written.length} new, ${result.updated.length} updated, ${result.unchanged.length} unchanged)`\n\t\t);\n\t\tif (result.dependenciesCopied.length > 0) {\n\t\t\tprintInfo(`${result.dependenciesCopied.length} runtime dependencies copied`);\n\t\t}\n\t\tprintSuccess(`${desc.name} subsystem installed with ${backend} backend.`);\n\t\tprintInfo(\n\t\t\t`Register ${capitalize(desc.name)}Module.forRoot({ backend: '${backend}' }) in your app.module.ts`\n\t\t);\n\t\treturn 0;\n\t}\n}\n\nfunction capitalize(s: string): string {\n\treturn s.length === 0 ? s : s[0].toUpperCase() + s.slice(1);\n}\n\n// ---------------------------------------------------------------------------\n// SubsystemListCommand\n// ---------------------------------------------------------------------------\n\nexport class SubsystemListCommand extends Command {\n\tstatic paths = [['subsystem', 'list']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'List installed and available subsystems',\n\t});\n\n\tformat = Option.String('--format', 'plain');\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json || this.format === 'json') setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tconfigPath: this.configPath,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: true,\n\t\t});\n\n\t\tconst installed = await detectInstalledSubsystems(ctx);\n\t\tconst byName = new Map<string, InstalledSubsystem>();\n\t\tfor (const i of installed) byName.set(i.name, i);\n\n\t\tconst rows = SUBSYSTEMS.map((s) => {\n\t\t\tconst inst = byName.get(s.name);\n\t\t\treturn {\n\t\t\t\tname: s.name,\n\t\t\t\tstatus: inst ? 'installed' : 'available',\n\t\t\t\tbackend: inst ? inst.backend : null,\n\t\t\t\tpath: inst ? path.relative(ctx.cwd, inst.path) || inst.path : null,\n\t\t\t};\n\t\t});\n\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({ command: 'subsystem list', subsystems: rows });\n\t\t\treturn 0;\n\t\t}\n\n\t\tconst pad = (s: string, n: number) => (s.length >= n ? s : s + ' '.repeat(n - s.length));\n\t\tconsole.log(\n\t\t\ttheme.muted(`${pad('NAME', 10)}${pad('STATUS', 12)}${pad('BACKEND', 12)}PATH`)\n\t\t);\n\t\tfor (const r of rows) {\n\t\t\tconsole.log(\n\t\t\t\t`${pad(r.name, 10)}${pad(r.status, 12)}${pad(r.backend ?? '—', 12)}${r.path ?? '—'}`\n\t\t\t);\n\t\t}\n\t\treturn 0;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// SubsystemRemoveCommand (stub)\n// ---------------------------------------------------------------------------\n\nexport class SubsystemRemoveCommand extends Command {\n\tstatic paths = [['subsystem', 'remove']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'Remove a subsystem (not yet implemented)',\n\t});\n\n\tname = Option.String({ required: true });\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json) setJsonMode(true);\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({\n\t\t\t\tcommand: 'subsystem remove',\n\t\t\t\tstatus: 'not-implemented',\n\t\t\t\tmessage:\n\t\t\t\t\t'Manually delete the subsystem directory and remove the module registration from your app.module.ts.',\n\t\t\t});\n\t\t\treturn 1;\n\t\t}\n\t\tprintError('subsystem remove is not yet implemented.');\n\t\tconsole.log(\n\t\t\ttheme.muted(\n\t\t\t\t' Manually delete the subsystem directory and remove the module\\n registration from your app.module.ts.'\n\t\t\t)\n\t\t);\n\t\treturn 1;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// NounModule default export\n// ---------------------------------------------------------------------------\n\nconst subsystemNoun: NounModule = {\n\tname: 'subsystem',\n\tcommandClasses: [\n\t\tSubsystemInstallCommand,\n\t\tSubsystemListCommand,\n\t\tSubsystemRemoveCommand,\n\t] as CommandClass[],\n\tsummary,\n\thints,\n};\n\nexport default subsystemNoun;\n","/**\n * Init scaffold — compute and (optionally) apply the file set `codegen\n * project init` writes. Pure planning functions + a `writePlan()` actor so\n * unit tests can inspect the plan without hitting the filesystem.\n *\n * Every scaffolded file matches the skeleton in docs/CONSUMER-SETUP.md. The\n * shim files use a computed relative path back to the codegen-patterns\n * runtime so consumers in sibling/workspace/installed layouts all work.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { stringify as stringifyYaml } from 'yaml';\n\nimport type { Context } from './context.js';\nimport { scanProject, generateConfig } from '../../scanner/index.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type PlanAction = 'create' | 'skip' | 'merge' | 'overwrite';\n\nexport interface PlanEntry {\n\t/** Absolute path of the target file or directory. */\n\tpath: string;\n\t/** Relative path, for display. */\n\trelPath: string;\n\t/** What we plan to do. */\n\taction: PlanAction;\n\t/** File contents to write (undefined for directory-only entries). */\n\tcontent?: string;\n\t/** Human-readable reason the entry resolved this way. */\n\treason?: string;\n\t/** True if this entry represents a directory (mkdir), not a file. */\n\tdirectory?: boolean;\n}\n\nexport interface InitPlan {\n\tentries: PlanEntry[];\n\t/** High-level summary for the user (config snapshot, detected framework). */\n\tsummary: {\n\t\tcwd: string;\n\t\tframework: string;\n\t\torm: string;\n\t\tarchitecture: string;\n\t\tfrontend: boolean;\n\t\truntimePath: string;\n\t};\n}\n\nexport interface InitOptions {\n\tcwd: string;\n\t/** Pass --force — overwrite non-directory files that already exist. */\n\tforce?: boolean;\n\t/** Create tsconfig.json if it doesn't exist. */\n\twithTsconfig?: boolean;\n\t/** Override the detected runtime path (for tests). */\n\truntimePath?: string;\n\t/** Skip running the scanner (use when the caller already has a context). */\n\tskipScan?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime path resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Compute the relative path from `<cwd>/shared/base-classes/` (or any shim\n * directory at depth 2 under cwd) back to the codegen-patterns `runtime/`.\n *\n * Strategy:\n * 1. Find the runtime source. It's bundled with this CLI at\n * `<packageRoot>/runtime/`.\n * 2. Resolve the relative path from the shim directory. For most layouts\n * (sibling repo, workspace dep) this produces `../../../codegen-patterns/\n * runtime` or `../../node_modules/@pattern-stack/codegen/runtime` — either\n * works as an import specifier.\n */\nexport function resolveRuntimePath(cwd: string): string {\n\t// src/cli/shared/init-scaffold.ts → ../../../runtime\n\tconst runtimeAbs = path.resolve(import.meta.dirname, '..', '..', '..', 'runtime');\n\t// Shim files live at <cwd>/shared/<subdir>/<file>.ts — that's depth 3.\n\t// Compute relative from <cwd>/shared/base-classes/ (representative).\n\tconst shimDir = path.join(cwd, 'shared', 'base-classes');\n\treturn path.relative(shimDir, runtimeAbs);\n}\n\nfunction resolveRuntimePathFor(cwd: string, shimRelDir: string): string {\n\tconst runtimeAbs = path.resolve(import.meta.dirname, '..', '..', '..', 'runtime');\n\tconst shimDir = path.join(cwd, shimRelDir);\n\treturn path.relative(shimDir, runtimeAbs);\n}\n\n// ---------------------------------------------------------------------------\n// Content builders\n// ---------------------------------------------------------------------------\n\nconst BASE_CLASS_SHIMS: Array<{ file: string; exportLine: (rt: string) => string }> = [\n\t{\n\t\tfile: 'base-repository.ts',\n\t\texportLine: (rt) => `export * from '${rt}/base-classes/base-repository';\\n`,\n\t},\n\t{\n\t\tfile: 'base-service.ts',\n\t\texportLine: (rt) => `export * from '${rt}/base-classes/base-service';\\n`,\n\t},\n\t{\n\t\tfile: 'synced-entity-repository.ts',\n\t\texportLine: (rt) =>\n\t\t\t`export * from '${rt}/base-classes/synced-entity-repository';\\n`,\n\t},\n\t{\n\t\tfile: 'synced-entity-service.ts',\n\t\texportLine: (rt) => `export * from '${rt}/base-classes/synced-entity-service';\\n`,\n\t},\n\t{\n\t\tfile: 'activity-entity-repository.ts',\n\t\texportLine: (rt) =>\n\t\t\t`export * from '${rt}/base-classes/activity-entity-repository';\\n`,\n\t},\n\t{\n\t\tfile: 'activity-entity-service.ts',\n\t\texportLine: (rt) =>\n\t\t\t`export * from '${rt}/base-classes/activity-entity-service';\\n`,\n\t},\n\t{\n\t\tfile: 'metadata-entity-repository.ts',\n\t\texportLine: (rt) =>\n\t\t\t`export * from '${rt}/base-classes/metadata-entity-repository';\\n`,\n\t},\n\t{\n\t\tfile: 'metadata-entity-service.ts',\n\t\texportLine: (rt) =>\n\t\t\t`export * from '${rt}/base-classes/metadata-entity-service';\\n`,\n\t},\n\t{\n\t\tfile: 'knowledge-entity-repository.ts',\n\t\texportLine: (rt) =>\n\t\t\t`export * from '${rt}/base-classes/knowledge-entity-repository';\\n`,\n\t},\n\t{\n\t\tfile: 'knowledge-entity-service.ts',\n\t\texportLine: (rt) =>\n\t\t\t`export * from '${rt}/base-classes/knowledge-entity-service';\\n`,\n\t},\n\t{\n\t\tfile: 'with-analytics.ts',\n\t\texportLine: (rt) => `export { WithAnalytics } from '${rt}/base-classes/with-analytics';\\n`,\n\t},\n];\n\nfunction databaseModuleContent(): string {\n\treturn `import { Module, Global } from '@nestjs/common';\nimport { drizzle } from 'drizzle-orm/node-postgres';\nimport { Pool } from 'pg';\nimport * as schema from '../../schema';\nimport { DRIZZLE } from '../constants/tokens';\n\nexport { DRIZZLE };\nexport type DrizzleDB = ReturnType<typeof drizzle<typeof schema>>;\n\n/**\n * DatabaseModule — provides the DRIZZLE injection token globally.\n * Import once in AppModule, before any generated module.\n */\n@Global()\n@Module({\n providers: [\n {\n provide: DRIZZLE,\n useFactory: () => {\n const pool = new Pool({\n connectionString: process.env.DATABASE_URL ?? 'postgresql://localhost:5432/app_dev',\n });\n return drizzle(pool, { schema });\n },\n },\n ],\n exports: [DRIZZLE],\n})\nexport class DatabaseModule {}\n`;\n}\n\nfunction tokensShim(cwd: string): string {\n\tconst rt = resolveRuntimePathFor(cwd, 'shared/constants');\n\treturn `/**\n * Re-export DRIZZLE injection token from the codegen runtime.\n * Generated code imports from '@shared/constants/tokens'.\n */\nexport { DRIZZLE } from '${rt}/constants/tokens';\n`;\n}\n\nfunction drizzleTypeShim(cwd: string): string {\n\tconst rt = resolveRuntimePathFor(cwd, 'shared/types');\n\treturn `/**\n * Re-export the DrizzleClient type from the codegen runtime.\n * Generated code imports from '@shared/types/drizzle'.\n */\nexport type { DrizzleClient } from '${rt}/types/drizzle';\n`;\n}\n\nfunction appModuleContent(): string {\n\treturn `import { Module } from '@nestjs/common';\nimport { DatabaseModule } from '../shared/database/database.module';\nimport { GENERATED_MODULES } from './generated/modules';\n\n/**\n * AppModule — wires DatabaseModule (global) + the GENERATED_MODULES barrel.\n *\n * DatabaseModule must come first — it provides the DRIZZLE token that every\n * generated repository depends on.\n */\n@Module({\n imports: [DatabaseModule, ...GENERATED_MODULES],\n})\nexport class AppModule {}\n`;\n}\n\nfunction rootSchemaContent(): string {\n\treturn `/**\n * Drizzle schema root.\n * Re-exports the generated schema barrel. Codegen owns src/generated/schema.ts\n * — add or remove entity YAML to change the table set.\n */\nexport * from './src/generated/schema';\n`;\n}\n\nfunction emptyModulesBarrel(): string {\n\treturn `// AUTO-GENERATED — DO NOT EDIT.\n// Regenerated on every \\`codegen entity new\\` / \\`codegen entity new --all\\`.\n// See ADR-017.\nexport const GENERATED_MODULES: unknown[] = [];\n`;\n}\n\nfunction emptySchemaBarrel(): string {\n\treturn `// AUTO-GENERATED — DO NOT EDIT.\n// Regenerated on every \\`codegen entity new\\` / \\`codegen entity new --all\\`.\n// See ADR-017.\nexport {};\n`;\n}\n\nfunction exampleEntityYaml(): string {\n\treturn `# Example entity definition — delete or rename to get started.\n#\n# entity:\n# name: account\n# family: synced # base | synced | activity | metadata | knowledge\n#\n# fields:\n# name:\n# type: string\n# required: true\n# email:\n# type: string\n# status:\n# type: enum\n# choices: [active, inactive]\n#\n# queries:\n# - by: [email]\n# unique: true\n`;\n}\n\nfunction tsconfigTemplate(): string {\n\treturn `{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"Bundler\",\n \"experimentalDecorators\": true,\n \"emitDecoratorMetadata\": true,\n \"strict\": true,\n \"skipLibCheck\": true,\n \"resolveJsonModule\": true,\n \"baseUrl\": \".\",\n \"paths\": {\n \"@shared/*\": [\"./shared/*\"],\n \"@modules/*\": [\"./modules/*\"],\n \"@generated/*\": [\"./src/generated/*\"]\n },\n \"types\": [\"node\"]\n },\n \"include\": [\n \"src/**/*\",\n \"shared/**/*\",\n \"modules/**/*\",\n \"schema.ts\",\n \"drizzle.config.ts\"\n ]\n}\n`;\n}\n\n// ---------------------------------------------------------------------------\n// tsconfig merge\n// ---------------------------------------------------------------------------\n\nconst REQUIRED_ALIASES: Record<string, string[]> = {\n\t'@shared/*': ['./shared/*'],\n\t'@modules/*': ['./modules/*'],\n\t'@generated/*': ['./src/generated/*'],\n};\n\ninterface TsconfigMergeResult {\n\tcontent: string;\n\tadded: string[];\n\tunchanged: boolean;\n}\n\n/**\n * Strip JSONC single-line (//) and block (/* ... *&#47;) comments so\n * JSON.parse can handle a typical tsconfig.json authored by `bun init` or\n * similar tooling. Deliberately simple — doesn't handle comment-looking\n * substrings inside string literals, which is acceptable because tsconfig\n * values are well-known shapes.\n */\nfunction stripJsonComments(raw: string): string {\n\tlet out = '';\n\tlet i = 0;\n\tlet inString = false;\n\tlet stringChar = '';\n\twhile (i < raw.length) {\n\t\tconst c = raw[i];\n\t\tconst next = raw[i + 1];\n\t\tif (inString) {\n\t\t\tout += c;\n\t\t\tif (c === '\\\\' && i + 1 < raw.length) {\n\t\t\t\tout += next;\n\t\t\t\ti += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (c === stringChar) inString = false;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (c === '\"' || c === \"'\") {\n\t\t\tinString = true;\n\t\t\tstringChar = c;\n\t\t\tout += c;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (c === '/' && next === '/') {\n\t\t\t// single-line comment — skip to newline\n\t\t\twhile (i < raw.length && raw[i] !== '\\n') i++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (c === '/' && next === '*') {\n\t\t\ti += 2;\n\t\t\twhile (i < raw.length && !(raw[i] === '*' && raw[i + 1] === '/')) i++;\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tout += c;\n\t\ti++;\n\t}\n\t// Strip trailing commas before ] and }\n\treturn out.replace(/,\\s*([\\]}])/g, '$1');\n}\n\nconst REQUIRED_COMPILER_OPTIONS: Record<string, unknown> = {\n\texperimentalDecorators: true,\n\temitDecoratorMetadata: true,\n};\n\n/**\n * Idempotent merge of required path aliases + compiler options into an\n * existing tsconfig. Only adds missing entries — never clobbers user-\n * authored paths or flags. Tolerates JSONC via a comment-stripping pass.\n */\nexport function mergeTsconfig(raw: string): TsconfigMergeResult & { parseError?: string } {\n\tlet parsed: Record<string, unknown>;\n\ttry {\n\t\tparsed = JSON.parse(stripJsonComments(raw));\n\t} catch (err: unknown) {\n\t\treturn {\n\t\t\tcontent: raw,\n\t\t\tadded: [],\n\t\t\tunchanged: true,\n\t\t\tparseError: err instanceof Error ? err.message : String(err),\n\t\t};\n\t}\n\n\tconst compilerOptions = (parsed.compilerOptions ?? {}) as Record<string, unknown>;\n\tconst paths = (compilerOptions.paths ?? {}) as Record<string, unknown>;\n\n\tconst added: string[] = [];\n\tfor (const [alias, target] of Object.entries(REQUIRED_ALIASES)) {\n\t\tif (!(alias in paths)) {\n\t\t\tpaths[alias] = target;\n\t\t\tadded.push(alias);\n\t\t}\n\t}\n\n\t// Also ensure decorator flags are enabled — NestJS generated code uses them.\n\tfor (const [opt, value] of Object.entries(REQUIRED_COMPILER_OPTIONS)) {\n\t\tif (compilerOptions[opt] === undefined) {\n\t\t\tcompilerOptions[opt] = value;\n\t\t\tadded.push(opt);\n\t\t}\n\t}\n\n\t// Verbatim module syntax + allowImportingTsExtensions (bun init defaults)\n\t// conflict with NestJS decorator metadata — turn them off for decorated code.\n\tif (compilerOptions.verbatimModuleSyntax === true) {\n\t\tcompilerOptions.verbatimModuleSyntax = false;\n\t\tadded.push('verbatimModuleSyntax=false');\n\t}\n\n\tif (added.length === 0) {\n\t\treturn { content: raw, added: [], unchanged: true };\n\t}\n\n\tcompilerOptions.paths = paths;\n\tif (compilerOptions.baseUrl === undefined) compilerOptions.baseUrl = '.';\n\tparsed.compilerOptions = compilerOptions;\n\n\treturn {\n\t\tcontent: JSON.stringify(parsed, null, 2) + '\\n',\n\t\tadded,\n\t\tunchanged: false,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Planner\n// ---------------------------------------------------------------------------\n\nfunction relOf(cwd: string, abs: string): string {\n\treturn path.relative(cwd, abs) || abs;\n}\n\nfunction fileEntry(\n\tcwd: string,\n\tabsPath: string,\n\tcontent: string,\n\topts: { force?: boolean; skipReason?: string }\n): PlanEntry {\n\tconst exists = fs.existsSync(absPath);\n\tlet action: PlanAction;\n\tlet reason: string | undefined = opts.skipReason;\n\tif (!exists) {\n\t\taction = 'create';\n\t} else if (opts.force) {\n\t\taction = 'overwrite';\n\t\treason = 'exists — --force';\n\t} else {\n\t\taction = 'skip';\n\t\treason = opts.skipReason ?? 'already exists';\n\t}\n\treturn { path: absPath, relPath: relOf(cwd, absPath), action, content, reason };\n}\n\nfunction dirEntry(cwd: string, absPath: string): PlanEntry {\n\tconst exists = fs.existsSync(absPath);\n\treturn {\n\t\tpath: absPath,\n\t\trelPath: relOf(cwd, absPath),\n\t\taction: exists ? 'skip' : 'create',\n\t\tdirectory: true,\n\t\treason: exists ? 'already exists' : undefined,\n\t};\n}\n\n/**\n * Build the complete init plan without touching disk.\n *\n * Detection: if `ctx.framework` is provided (not null), it's used; otherwise\n * we run `scanProject()` unless `skipScan` is set.\n */\nexport async function buildInitPlan(\n\tctx: Context,\n\toptions: InitOptions\n): Promise<InitPlan> {\n\tconst cwd = options.cwd;\n\tconst force = Boolean(options.force);\n\n\t// Detection — drive config defaults.\n\t//\n\t// Architecture default: 'clean-lite-ps'. The CONSUMER-SETUP.md flow and\n\t// the codegen-pattern-demo-app both use clean-lite-ps; it's the\n\t// supported consumer path. The scanner only overrides when it finds\n\t// high-confidence evidence of a different layout (e.g. existing\n\t// domain/ + application/ directories).\n\tlet framework = 'nestjs';\n\tlet orm = 'drizzle';\n\tlet architecture: 'clean' | 'clean-lite-ps' = 'clean-lite-ps';\n\tlet frontend = false;\n\n\tif (!options.skipScan) {\n\t\ttry {\n\t\t\tconst profile = ctx.framework ?? (await scanProject({ directory: cwd }));\n\t\t\tconst proposed = generateConfig(profile);\n\t\t\tframework = proposed.framework;\n\t\t\torm = proposed.orm;\n\t\t\t// Only override architecture when the scanner detected actual\n\t\t\t// clean-architecture evidence (domain/, application/ dirs). A\n\t\t\t// fresh project that resolves to 'flat' with high confidence\n\t\t\t// should stay at the clean-lite-ps default — otherwise init\n\t\t\t// would emit a config that asks codegen to generate files into\n\t\t\t// presentation/ and infrastructure/ directories that don't\n\t\t\t// (and shouldn't) exist.\n\t\t\tif (\n\t\t\t\tprofile.architecture.detected === 'clean' &&\n\t\t\t\tprofile.architecture.confidence >= 50\n\t\t\t) {\n\t\t\t\tarchitecture = proposed.generate.architecture;\n\t\t\t}\n\t\t\tfrontend = proposed.generate.frontend;\n\t\t} catch {\n\t\t\t// Detection failed — keep defaults.\n\t\t}\n\t}\n\n\tconst runtimePath = options.runtimePath ?? resolveRuntimePath(cwd);\n\n\tconst entries: PlanEntry[] = [];\n\n\t// 1. codegen.config.yaml\n\t{\n\t\tconst configPath = path.join(cwd, 'codegen.config.yaml');\n\t\tconst config = {\n\t\t\tpaths: {\n\t\t\t\tbackend_src: '.',\n\t\t\t\tentities_dir: 'entities',\n\t\t\t\tgenerated: 'src/generated',\n\t\t\t},\n\t\t\tgenerate: {\n\t\t\t\tarchitecture,\n\t\t\t\tfrontend,\n\t\t\t\tcommands: true,\n\t\t\t\tqueries: true,\n\t\t\t},\n\t\t\tnaming: {\n\t\t\t\tfileCase: 'kebab-case',\n\t\t\t\tsuffixStyle: 'dotted',\n\t\t\t\tterminology: {\n\t\t\t\t\tcommand: 'use-case',\n\t\t\t\t\tquery: 'use-case',\n\t\t\t\t},\n\t\t\t},\n\t\t\tdatabase: {\n\t\t\t\tdialect: 'postgres',\n\t\t\t},\n\t\t};\n\t\tconst content = stringifyYaml(config, { indent: 2 });\n\t\tentries.push(fileEntry(cwd, configPath, content, { force }));\n\t}\n\n\t// 2. tsconfig.json — idempotent merge\n\t{\n\t\tconst tsconfigPath = path.join(cwd, 'tsconfig.json');\n\t\tif (fs.existsSync(tsconfigPath)) {\n\t\t\tconst raw = fs.readFileSync(tsconfigPath, 'utf-8');\n\t\t\tconst merged = mergeTsconfig(raw);\n\t\t\tif (merged.parseError) {\n\t\t\t\tentries.push({\n\t\t\t\t\tpath: tsconfigPath,\n\t\t\t\t\trelPath: relOf(cwd, tsconfigPath),\n\t\t\t\t\taction: 'skip',\n\t\t\t\t\treason: `unable to parse (${merged.parseError}); add aliases manually`,\n\t\t\t\t});\n\t\t\t} else if (merged.unchanged) {\n\t\t\t\tentries.push({\n\t\t\t\t\tpath: tsconfigPath,\n\t\t\t\t\trelPath: relOf(cwd, tsconfigPath),\n\t\t\t\t\taction: 'skip',\n\t\t\t\t\treason: 'path aliases already present',\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tentries.push({\n\t\t\t\t\tpath: tsconfigPath,\n\t\t\t\t\trelPath: relOf(cwd, tsconfigPath),\n\t\t\t\t\taction: 'merge',\n\t\t\t\t\tcontent: merged.content,\n\t\t\t\t\treason: `add aliases: ${merged.added.join(', ')}`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (options.withTsconfig) {\n\t\t\tentries.push({\n\t\t\t\tpath: tsconfigPath,\n\t\t\t\trelPath: relOf(cwd, tsconfigPath),\n\t\t\t\taction: 'create',\n\t\t\t\tcontent: tsconfigTemplate(),\n\t\t\t\treason: 'new tsconfig.json',\n\t\t\t});\n\t\t} else {\n\t\t\tentries.push({\n\t\t\t\tpath: tsconfigPath,\n\t\t\t\trelPath: relOf(cwd, tsconfigPath),\n\t\t\t\taction: 'skip',\n\t\t\t\treason: 'missing — pass --with-tsconfig to create one',\n\t\t\t});\n\t\t}\n\t}\n\n\t// 3. shared/database/database.module.ts\n\tentries.push(\n\t\tfileEntry(\n\t\t\tcwd,\n\t\t\tpath.join(cwd, 'shared', 'database', 'database.module.ts'),\n\t\t\tdatabaseModuleContent(),\n\t\t\t{ force }\n\t\t)\n\t);\n\n\t// 4. shared/constants/tokens.ts\n\tentries.push(\n\t\tfileEntry(cwd, path.join(cwd, 'shared', 'constants', 'tokens.ts'), tokensShim(cwd), {\n\t\t\tforce,\n\t\t})\n\t);\n\n\t// 5. shared/types/drizzle.ts\n\tentries.push(\n\t\tfileEntry(cwd, path.join(cwd, 'shared', 'types', 'drizzle.ts'), drizzleTypeShim(cwd), {\n\t\t\tforce,\n\t\t})\n\t);\n\n\t// 6. shared/base-classes/*\n\t{\n\t\tconst rt = resolveRuntimePathFor(cwd, 'shared/base-classes');\n\t\tfor (const shim of BASE_CLASS_SHIMS) {\n\t\t\tentries.push(\n\t\t\t\tfileEntry(\n\t\t\t\t\tcwd,\n\t\t\t\t\tpath.join(cwd, 'shared', 'base-classes', shim.file),\n\t\t\t\t\tshim.exportLine(rt),\n\t\t\t\t\t{ force }\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\t}\n\n\t// 7. src/generated/{modules,schema}.ts — empty barrels\n\tentries.push(\n\t\tfileEntry(\n\t\t\tcwd,\n\t\t\tpath.join(cwd, 'src', 'generated', 'modules.ts'),\n\t\t\temptyModulesBarrel(),\n\t\t\t{ force }\n\t\t)\n\t);\n\tentries.push(\n\t\tfileEntry(\n\t\t\tcwd,\n\t\t\tpath.join(cwd, 'src', 'generated', 'schema.ts'),\n\t\t\temptySchemaBarrel(),\n\t\t\t{ force }\n\t\t)\n\t);\n\n\t// 8. src/app.module.ts — only if missing (never clobber user auth'd module)\n\t{\n\t\tconst appModulePath = path.join(cwd, 'src', 'app.module.ts');\n\t\tif (!fs.existsSync(appModulePath)) {\n\t\t\tentries.push({\n\t\t\t\tpath: appModulePath,\n\t\t\t\trelPath: relOf(cwd, appModulePath),\n\t\t\t\taction: 'create',\n\t\t\t\tcontent: appModuleContent(),\n\t\t\t});\n\t\t} else {\n\t\t\tentries.push({\n\t\t\t\tpath: appModulePath,\n\t\t\t\trelPath: relOf(cwd, appModulePath),\n\t\t\t\taction: 'skip',\n\t\t\t\treason: 'exists — wire DatabaseModule + GENERATED_MODULES manually',\n\t\t\t});\n\t\t}\n\t}\n\n\t// 9. schema.ts — root\n\t{\n\t\tconst schemaPath = path.join(cwd, 'schema.ts');\n\t\tif (!fs.existsSync(schemaPath)) {\n\t\t\tentries.push({\n\t\t\t\tpath: schemaPath,\n\t\t\t\trelPath: relOf(cwd, schemaPath),\n\t\t\t\taction: 'create',\n\t\t\t\tcontent: rootSchemaContent(),\n\t\t\t});\n\t\t} else {\n\t\t\tentries.push({\n\t\t\t\tpath: schemaPath,\n\t\t\t\trelPath: relOf(cwd, schemaPath),\n\t\t\t\taction: 'skip',\n\t\t\t\treason: \"exists — ensure it re-exports './src/generated/schema'\",\n\t\t\t});\n\t\t}\n\t}\n\n\t// 10. entities/ + entities/example.yaml\n\tentries.push(dirEntry(cwd, path.join(cwd, 'entities')));\n\t{\n\t\tconst examplePath = path.join(cwd, 'entities', 'example.yaml');\n\t\tif (!fs.existsSync(examplePath)) {\n\t\t\tentries.push({\n\t\t\t\tpath: examplePath,\n\t\t\t\trelPath: relOf(cwd, examplePath),\n\t\t\t\taction: 'create',\n\t\t\t\tcontent: exampleEntityYaml(),\n\t\t\t});\n\t\t} else {\n\t\t\tentries.push({\n\t\t\t\tpath: examplePath,\n\t\t\t\trelPath: relOf(cwd, examplePath),\n\t\t\t\taction: 'skip',\n\t\t\t\treason: 'already exists',\n\t\t\t});\n\t\t}\n\t}\n\n\treturn {\n\t\tentries,\n\t\tsummary: {\n\t\t\tcwd,\n\t\t\tframework,\n\t\t\torm,\n\t\t\tarchitecture,\n\t\t\tfrontend,\n\t\t\truntimePath,\n\t\t},\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Writer\n// ---------------------------------------------------------------------------\n\nexport interface WriteResult {\n\tcreated: PlanEntry[];\n\tmerged: PlanEntry[];\n\toverwritten: PlanEntry[];\n\tskipped: PlanEntry[];\n}\n\nexport function writePlan(plan: InitPlan): WriteResult {\n\tconst created: PlanEntry[] = [];\n\tconst merged: PlanEntry[] = [];\n\tconst overwritten: PlanEntry[] = [];\n\tconst skipped: PlanEntry[] = [];\n\n\tfor (const e of plan.entries) {\n\t\tif (e.action === 'skip') {\n\t\t\tskipped.push(e);\n\t\t\tcontinue;\n\t\t}\n\t\tif (e.directory) {\n\t\t\tfs.mkdirSync(e.path, { recursive: true });\n\t\t\tcreated.push(e);\n\t\t\tcontinue;\n\t\t}\n\t\tif (e.content === undefined) {\n\t\t\tskipped.push(e);\n\t\t\tcontinue;\n\t\t}\n\t\tfs.mkdirSync(path.dirname(e.path), { recursive: true });\n\t\tfs.writeFileSync(e.path, e.content, 'utf-8');\n\t\tif (e.action === 'create') created.push(e);\n\t\telse if (e.action === 'merge') merged.push(e);\n\t\telse if (e.action === 'overwrite') overwritten.push(e);\n\t}\n\n\treturn { created, merged, overwritten, skipped };\n}\n","/**\n * Project noun — codegen project / init / scan / config / inspect / graph\n *\n * Implements the `project` surface:\n * - codegen project summary pane (initialized? framework? config?)\n * - codegen project init scaffold a consumer project (see init-scaffold.ts)\n * - codegen project scan run scanner + propose/write codegen.config.yaml\n * - codegen project config print resolved config (YAML or JSON)\n * - codegen project inspect legacy analyze/stats/doc/manifest/suggestions\n * - codegen project graph visualize entity-relationship graph in browser\n *\n * Legacy verbs (`analyze`, `stats`, `doc`, `manifest`, `suggestions`) from\n * `src/cli.ts` are hosted under `codegen project inspect --kind <k>` to keep\n * the noun surface tidy while preserving behavior.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport readline from 'node:readline';\nimport { Command, Option } from 'clipanion';\nimport type { CommandClass } from 'clipanion';\nimport { stringify as stringifyYaml } from 'yaml';\n\nimport { analyzeDomain } from '../../index.js';\nimport { serializeDomainGraph } from '../../analyzer/serialize-graph.js';\nimport {\n\tsuggestTransitiveRelationships,\n\treadManifest,\n\twriteManifest,\n\tbuildManifest,\n\tisManifestStale,\n\tgetPendingSuggestions,\n\tupdateSuggestionStatus,\n\tupdateAllSuggestionStatus,\n\tgetManifestDir,\n} from '../../analyzer/index.js';\nimport { formatConsole } from '../../formatters/console-formatter.js';\nimport { formatJson, formatStatsJson } from '../../formatters/json-formatter.js';\nimport { formatMarkdown } from '../../formatters/markdown-formatter.js';\nimport { scanProject, generateConfig } from '../../scanner/index.js';\n\nimport { loadContext, type Context } from '../shared/context.js';\nimport { buildInitPlan, writePlan, type InitPlan } from '../shared/init-scaffold.js';\n\nimport { theme } from '../ui/theme.js';\nimport { icons } from '../ui/icons.js';\nimport { printError, printInfo, printSuccess, printWarning } from '../ui/output.js';\nimport { isJsonMode, printJson, setJsonMode } from '../ui/json.js';\nimport type { PaneOutput } from '../ui/pane.js';\nimport type { Hint } from '../ui/hints.js';\nimport type { NounModule } from '../noun-module.js';\n\n// ---------------------------------------------------------------------------\n// summary + hints\n// ---------------------------------------------------------------------------\n\nasync function summary(ctx: Context): Promise<PaneOutput> {\n\tif (!ctx.isInitialized) {\n\t\treturn {\n\t\t\ttitle: 'project',\n\t\t\tbody: [\n\t\t\t\t`${theme.warning(icons.warning)} project not initialized`,\n\t\t\t\t'',\n\t\t\t\t' no codegen.config.yaml detected',\n\t\t\t\t' no entities/ directory detected',\n\t\t\t],\n\t\t\tfooter: `cwd: ${ctx.cwd}`,\n\t\t};\n\t}\n\n\tconst body: string[] = [];\n\tbody.push(`${theme.success(icons.check)} project initialized`);\n\tbody.push('');\n\tbody.push(` config: ${ctx.configPath ?? '(none)'}`);\n\n\tconst fw = ctx.framework?.framework?.detected ?? 'unknown';\n\tconst orm = ctx.framework?.orm?.detected ?? 'unknown';\n\tconst arch =\n\t\t(ctx.config?.generate as { architecture?: string } | undefined)?.architecture ??\n\t\tctx.framework?.architecture?.detected ??\n\t\t'clean';\n\tconst generated =\n\t\t(ctx.config?.paths as { generated?: string } | undefined)?.generated ?? 'src/generated';\n\n\tbody.push(` framework: ${fw}`);\n\tbody.push(` orm: ${orm}`);\n\tbody.push(` architecture: ${arch}`);\n\tbody.push(` entities: ${ctx.entityCount}`);\n\tbody.push(` subsystems: ${ctx.installedSubsystems.length}/4 installed`);\n\tbody.push(` generated: ${generated}`);\n\n\treturn {\n\t\ttitle: 'project',\n\t\tbody,\n\t\tfooter: `cwd: ${ctx.cwd}`,\n\t};\n}\n\nasync function hints(ctx: Context): Promise<Hint[]> {\n\tif (!ctx.isInitialized) {\n\t\treturn [\n\t\t\t{ command: 'codegen init', description: 'Scaffold consumer project' },\n\t\t\t{ command: 'codegen project scan', description: 'Detect framework + ORM' },\n\t\t];\n\t}\n\tconst out: Hint[] = [\n\t\t{ command: 'codegen project config', description: 'Print resolved config' },\n\t];\n\tif (ctx.entityCount === 0) {\n\t\tout.push({\n\t\t\tcommand: 'codegen entity new entities/example.yaml',\n\t\t\tdescription: 'Generate first entity',\n\t\t});\n\t} else {\n\t\tout.push({ command: 'codegen entity', description: 'Entity summary + hints' });\n\t}\n\tif (ctx.installedSubsystems.length < 4) {\n\t\tout.push({\n\t\t\tcommand: 'codegen subsystem',\n\t\t\tdescription: 'Install events/jobs/cache/storage',\n\t\t});\n\t}\n\treturn out;\n}\n\n// ---------------------------------------------------------------------------\n// ProjectInitCommand\n// ---------------------------------------------------------------------------\n\nexport class ProjectInitCommand extends Command {\n\tstatic paths = [['project', 'init']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'Scaffold a consumer project (config, shims, barrels, app.module)',\n\t\texamples: [\n\t\t\t['Initialize with defaults', 'codegen project init --yes'],\n\t\t\t['Preview without writing', 'codegen project init --dry-run'],\n\t\t\t['Create tsconfig if missing', 'codegen project init --yes --with-tsconfig'],\n\t\t\t['Overwrite existing shims', 'codegen project init --force'],\n\t\t],\n\t});\n\n\tyes = Option.Boolean('--yes,-y', false);\n\tdryRun = Option.Boolean('--dry-run', false);\n\tforce = Option.Boolean('--force', false);\n\twithTsconfig = Option.Boolean('--with-tsconfig', false);\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json) setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: false,\n\t\t});\n\n\t\tconst plan = await buildInitPlan(ctx, {\n\t\t\tcwd: ctx.cwd,\n\t\t\tforce: this.force,\n\t\t\twithTsconfig: this.withTsconfig,\n\t\t\tskipScan: false,\n\t\t});\n\n\t\tif (this.force && !isJsonMode()) {\n\t\t\tprintWarning('--force: existing scaffold files will be overwritten.');\n\t\t}\n\n\t\tif (this.dryRun) {\n\t\t\treturn renderPlanOnly(plan, { dryRun: true });\n\t\t}\n\n\t\tif (!this.yes && !isJsonMode()) {\n\t\t\trenderPlanOnly(plan, { dryRun: false });\n\t\t\tconsole.log('');\n\t\t\tconst confirmed = await askConfirm('Proceed?');\n\t\t\tif (!confirmed) {\n\t\t\t\tprintInfo('Aborted.');\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tconsole.log('');\n\t\t}\n\n\t\tconst result = writePlan(plan);\n\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({\n\t\t\t\tcommand: 'project init',\n\t\t\t\tsummary: plan.summary,\n\t\t\t\tplanned: plan.entries.length,\n\t\t\t\tcreated: result.created.map((e) => e.relPath),\n\t\t\t\tmerged: result.merged.map((e) => e.relPath),\n\t\t\t\toverwritten: result.overwritten.map((e) => e.relPath),\n\t\t\t\tskipped: result.skipped.map((e) => ({ path: e.relPath, reason: e.reason })),\n\t\t\t});\n\t\t\treturn 0;\n\t\t}\n\n\t\tprintSuccess('project init complete');\n\t\tconsole.log('');\n\t\tconsole.log(` ${theme.muted('framework:')} ${plan.summary.framework}`);\n\t\tconsole.log(` ${theme.muted('orm:')} ${plan.summary.orm}`);\n\t\tconsole.log(` ${theme.muted('architecture:')} ${plan.summary.architecture}`);\n\t\tconsole.log(` ${theme.muted('frontend:')} ${plan.summary.frontend}`);\n\t\tconsole.log('');\n\n\t\tfor (const e of result.created) {\n\t\t\tconsole.log(` ${theme.success(icons.check)} ${theme.muted('create ')} ${e.relPath}`);\n\t\t}\n\t\tfor (const e of result.merged) {\n\t\t\tconsole.log(\n\t\t\t\t` ${theme.success(icons.check)} ${theme.muted('merge ')} ${e.relPath}${\n\t\t\t\t\te.reason ? theme.muted(' (' + e.reason + ')') : ''\n\t\t\t\t}`\n\t\t\t);\n\t\t}\n\t\tfor (const e of result.overwritten) {\n\t\t\tconsole.log(\n\t\t\t\t` ${theme.warning(icons.warning)} ${theme.muted('replace ')} ${e.relPath}`\n\t\t\t);\n\t\t}\n\t\tfor (const e of result.skipped) {\n\t\t\tconsole.log(\n\t\t\t\t` ${theme.muted(icons.dash)} ${theme.muted('skip ')} ${e.relPath}${\n\t\t\t\t\te.reason ? theme.muted(' (' + e.reason + ')') : ''\n\t\t\t\t}`\n\t\t\t);\n\t\t}\n\t\tconsole.log('');\n\t\tprintInfo('Next steps:');\n\t\tconsole.log(` 1. ${theme.system('bun add')} the peer deps (see docs/CONSUMER-SETUP.md)`);\n\t\tconsole.log(\n\t\t\t` 2. ${theme.system('codegen entity new entities/<file>.yaml')} to generate your first entity`\n\t\t);\n\t\tconsole.log(` 3. ${theme.system('bunx tsc --noEmit')} to verify the scaffold typechecks`);\n\n\t\treturn 0;\n\t}\n}\n\nfunction askConfirm(question: string): Promise<boolean> {\n\tconst rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n\treturn new Promise((resolve) => {\n\t\trl.question(`${question} [Y/n] `, (answer) => {\n\t\t\trl.close();\n\t\t\tresolve(answer.trim().toLowerCase() !== 'n');\n\t\t});\n\t});\n}\n\nfunction renderPlanOnly(plan: InitPlan, opts: { dryRun: boolean }): number {\n\tif (isJsonMode()) {\n\t\tprintJson({\n\t\t\tcommand: 'project init',\n\t\t\tdryRun: opts.dryRun,\n\t\t\tsummary: plan.summary,\n\t\t\tentries: plan.entries.map((e) => ({\n\t\t\t\tpath: e.relPath,\n\t\t\t\taction: e.action,\n\t\t\t\treason: e.reason,\n\t\t\t\tdirectory: Boolean(e.directory),\n\t\t\t})),\n\t\t});\n\t\treturn 0;\n\t}\n\tprintInfo(`Dry run — ${plan.entries.length} entries planned`);\n\tconsole.log('');\n\tconsole.log(` ${theme.muted('framework:')} ${plan.summary.framework}`);\n\tconsole.log(` ${theme.muted('orm:')} ${plan.summary.orm}`);\n\tconsole.log(` ${theme.muted('architecture:')} ${plan.summary.architecture}`);\n\tconsole.log('');\n\tfor (const e of plan.entries) {\n\t\tconst icon =\n\t\t\te.action === 'create'\n\t\t\t\t? theme.success(icons.check)\n\t\t\t\t: e.action === 'merge'\n\t\t\t\t\t? theme.success(icons.arrow)\n\t\t\t\t\t: e.action === 'overwrite'\n\t\t\t\t\t\t? theme.warning(icons.warning)\n\t\t\t\t\t\t: theme.muted(icons.dash);\n\t\tconst tag = e.action.padEnd(8);\n\t\tconst reason = e.reason ? ` ${theme.muted('(' + e.reason + ')')}` : '';\n\t\tconsole.log(` ${icon} ${theme.muted(tag)} ${e.relPath}${reason}`);\n\t}\n\treturn 0;\n}\n\n// ---------------------------------------------------------------------------\n// ProjectScanCommand\n// ---------------------------------------------------------------------------\n\nexport class ProjectScanCommand extends Command {\n\tstatic paths = [['project', 'scan']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'Detect framework/ORM/architecture and propose a codegen.config.yaml',\n\t\texamples: [\n\t\t\t['Scan the current directory', 'codegen project scan'],\n\t\t\t['Write config without prompting', 'codegen project scan --write'],\n\t\t\t['Preview only', 'codegen project scan --dry-run'],\n\t\t],\n\t});\n\n\tdirectory = Option.String({ required: false });\n\twrite = Option.Boolean('--write', false);\n\tdryRun = Option.Boolean('--dry-run', false);\n\tverbose = Option.Boolean('--verbose,-v', false);\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json) setJsonMode(true);\n\t\tconst baseCwd = this.cwd ? path.resolve(this.cwd) : process.cwd();\n\t\tconst target = this.directory ? path.resolve(baseCwd, this.directory) : baseCwd;\n\n\t\tif (!fs.existsSync(target)) {\n\t\t\tprintError(`Directory not found: ${target}`);\n\t\t\treturn 1;\n\t\t}\n\n\t\tconst profile = await scanProject({ directory: target });\n\t\tconst config = generateConfig(profile);\n\n\t\tconst yamlConfig = {\n\t\t\tframework: config.framework,\n\t\t\torm: config.orm,\n\t\t\tlayout: {\n\t\t\t\tfolder_structure: config.folder_structure,\n\t\t\t\tfile_grouping: config.file_grouping,\n\t\t\t},\n\t\t\tnaming: config.naming,\n\t\t\tpaths: config.paths,\n\t\t\tgenerate: config.generate,\n\t\t\t_confidence: config.confidence,\n\t\t};\n\t\tconst yamlText = stringifyYaml(yamlConfig, { indent: 2 });\n\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({\n\t\t\t\tcommand: 'project scan',\n\t\t\t\tdirectory: target,\n\t\t\t\tprofile,\n\t\t\t\tproposed: config,\n\t\t\t});\n\t\t\treturn 0;\n\t\t}\n\n\t\tprintInfo(`Scanned ${target}`);\n\t\tconsole.log('');\n\t\tconsole.log(\n\t\t\t` framework: ${profile.framework.detected} ${theme.muted('(' + profile.framework.confidence + '%)')}`\n\t\t);\n\t\tconsole.log(\n\t\t\t` orm: ${profile.orm.detected} ${theme.muted('(' + profile.orm.confidence + '%)')}`\n\t\t);\n\t\tconsole.log(\n\t\t\t` architecture: ${profile.architecture.detected} ${theme.muted('(' + profile.architecture.confidence + '%)')}`\n\t\t);\n\t\tconsole.log(\n\t\t\t` naming: ${profile.naming.fileCase.detected} ${theme.muted('(' + profile.naming.fileCase.confidence + '%)')}`\n\t\t);\n\n\t\tif (this.verbose) {\n\t\t\tconsole.log('');\n\t\t\tprintMutedBlock('Evidence', [\n\t\t\t\t`framework: ${profile.framework.evidence.join(', ') || '—'}`,\n\t\t\t\t`orm: ${profile.orm.evidence.join(', ') || '—'}`,\n\t\t\t\t`architecture: ${profile.architecture.evidence.join(', ') || '—'}`,\n\t\t\t]);\n\t\t}\n\n\t\tconst outPath = path.join(target, 'codegen.config.yaml');\n\t\tconst existsNow = fs.existsSync(outPath);\n\n\t\tif (this.dryRun) {\n\t\t\tconsole.log('');\n\t\t\tprintInfo('Dry run — proposed codegen.config.yaml:');\n\t\t\tconsole.log('');\n\t\t\tconsole.log(yamlText);\n\t\t\treturn 0;\n\t\t}\n\n\t\tif (this.write) {\n\t\t\tif (existsNow) {\n\t\t\t\tprintWarning(`${outPath} already exists — pass --force via edit; skipping.`);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tfs.writeFileSync(outPath, yamlText);\n\t\t\tprintSuccess(`wrote ${outPath}`);\n\t\t\treturn 0;\n\t\t}\n\n\t\tconsole.log('');\n\t\tprintInfo(\n\t\t\t`Preview — re-run with ${theme.system('--write')} to save to ${theme.muted('codegen.config.yaml')}`\n\t\t);\n\t\tconsole.log('');\n\t\tconsole.log(yamlText);\n\t\treturn 0;\n\t}\n}\n\nfunction printMutedBlock(title: string, lines: string[]): void {\n\tif (isJsonMode()) return;\n\tconsole.log(theme.muted(title + ':'));\n\tfor (const l of lines) console.log(theme.muted(' ' + l));\n}\n\n// ---------------------------------------------------------------------------\n// ProjectConfigCommand\n// ---------------------------------------------------------------------------\n\nexport class ProjectConfigCommand extends Command {\n\tstatic paths = [['project', 'config']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'Print the resolved codegen config (YAML or JSON)',\n\t});\n\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json) setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tconfigPath: this.configPath,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: true,\n\t\t});\n\n\t\tconst resolved = {\n\t\t\tconfigPath: ctx.configPath,\n\t\t\tcwd: ctx.cwd,\n\t\t\tisInitialized: ctx.isInitialized,\n\t\t\tentityCount: ctx.entityCount,\n\t\t\tentitiesDir: ctx.entitiesDir,\n\t\t\tconfig: ctx.config ?? {},\n\t\t};\n\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({ command: 'project config', ...resolved });\n\t\t\treturn 0;\n\t\t}\n\n\t\tif (!ctx.isInitialized) {\n\t\t\tprintWarning('project is not initialized');\n\t\t\tprintInfo(`run ${theme.system('codegen init')} to scaffold a project`);\n\t\t\treturn 0;\n\t\t}\n\n\t\tprintInfo(`config: ${ctx.configPath ?? '(none)'}`);\n\t\tconsole.log('');\n\t\tconsole.log(stringifyYaml(ctx.config ?? {}, { indent: 2 }));\n\t\treturn 0;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// ProjectInspectCommand — analyze/stats/doc/manifest/suggestions\n// ---------------------------------------------------------------------------\n\ntype InspectKind = 'analyze' | 'stats' | 'doc' | 'manifest' | 'suggestions';\n\nexport class ProjectInspectCommand extends Command {\n\tstatic paths = [['project', 'inspect']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'Domain analysis, statistics, documentation, and manifest operations',\n\t\texamples: [\n\t\t\t['Full analysis', 'codegen project inspect --kind analyze'],\n\t\t\t['Statistics only', 'codegen project inspect --kind stats'],\n\t\t\t['Markdown docs', 'codegen project inspect --kind doc --output domain.md'],\n\t\t\t['Refresh manifest', 'codegen project inspect --kind manifest --force'],\n\t\t\t['Review suggestions', 'codegen project inspect --kind suggestions'],\n\t\t],\n\t});\n\n\tkind = Option.String('--kind', { required: true });\n\tdir = Option.String({ required: false });\n\tformat = Option.String('--format', 'console');\n\toutput = Option.String('--output,-o', { required: false });\n\tstrict = Option.Boolean('--strict', false);\n\tentity = Option.String('--entity', { required: false });\n\tforce = Option.Boolean('--force', false);\n\taccept = Option.String('--accept', { required: false });\n\tskip = Option.String('--skip', { required: false });\n\tacceptAll = Option.Boolean('--accept-all', false);\n\tskipAll = Option.Boolean('--skip-all', false);\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json || this.format === 'json') setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tconfigPath: this.configPath,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: true,\n\t\t});\n\n\t\tconst kind = this.kind as InspectKind;\n\n\t\tif (kind === 'suggestions') {\n\t\t\treturn this.runSuggestions(ctx);\n\t\t}\n\t\tif (kind === 'manifest') {\n\t\t\treturn this.runManifest(ctx);\n\t\t}\n\t\tif (kind === 'analyze' || kind === 'stats' || kind === 'doc') {\n\t\t\treturn this.runAnalysis(ctx, kind);\n\t\t}\n\n\t\tprintError(\n\t\t\t`Unknown --kind '${this.kind}'. Valid: analyze, stats, doc, manifest, suggestions`\n\t\t);\n\t\treturn 2;\n\t}\n\n\tprivate resolveEntitiesDir(ctx: Context): string | null {\n\t\tif (this.dir) return path.resolve(ctx.cwd, this.dir);\n\t\treturn ctx.entitiesDir ?? path.resolve(ctx.cwd, 'entities');\n\t}\n\n\tprivate async runAnalysis(\n\t\tctx: Context,\n\t\tkind: 'analyze' | 'stats' | 'doc'\n\t): Promise<number> {\n\t\tconst entitiesDir = this.resolveEntitiesDir(ctx);\n\t\tif (!entitiesDir || !fs.existsSync(entitiesDir)) {\n\t\t\tprintError(`Directory not found: ${entitiesDir ?? '(no entities/ dir)'}`);\n\t\t\treturn 1;\n\t\t}\n\n\t\tconst result = await analyzeDomain(entitiesDir);\n\n\t\tlet filtered = result;\n\t\tif (this.entity) {\n\t\t\tconst e = result.entities.find((x) => x.name === this.entity);\n\t\t\tif (!e) {\n\t\t\t\tprintError(`Entity not found: ${this.entity}`);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tfiltered = {\n\t\t\t\t...result,\n\t\t\t\tentities: [e],\n\t\t\t\tissues: result.issues.filter((i) => i.entity === this.entity || !i.entity),\n\t\t\t};\n\t\t}\n\n\t\tconst format = kind === 'doc' ? 'markdown' : (this.format as 'console' | 'json' | 'markdown');\n\t\tlet out: string;\n\t\tif (kind === 'stats') {\n\t\t\tout = format === 'json' ? formatStatsJson(filtered) : formatStatsConsole(filtered);\n\t\t} else if (format === 'json') {\n\t\t\tout = formatJson(filtered);\n\t\t} else if (format === 'markdown') {\n\t\t\tout = formatMarkdown(filtered);\n\t\t} else {\n\t\t\tout = formatConsole(filtered);\n\t\t}\n\n\t\tif (this.output) {\n\t\t\tfs.writeFileSync(this.output, out);\n\t\t\tif (!isJsonMode()) printSuccess(`wrote ${this.output}`);\n\t\t} else {\n\t\t\tconsole.log(out);\n\t\t}\n\n\t\tconst hasErrors = filtered.issues.some((i) => i.severity === 'error');\n\t\tconst hasWarnings = filtered.issues.some((i) => i.severity === 'warning');\n\t\tif (hasErrors) return 1;\n\t\tif (this.strict && hasWarnings) return 1;\n\t\treturn 0;\n\t}\n\n\tprivate async runManifest(ctx: Context): Promise<number> {\n\t\tconst entitiesDir = this.resolveEntitiesDir(ctx);\n\t\tif (!entitiesDir || !fs.existsSync(entitiesDir)) {\n\t\t\tprintError(`Directory not found: ${entitiesDir ?? '(no entities/ dir)'}`);\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (!this.force) {\n\t\t\tconst stale = await isManifestStale(ctx.cwd, entitiesDir);\n\t\t\tif (!stale) {\n\t\t\t\tif (isJsonMode()) {\n\t\t\t\t\tprintJson({ command: 'project inspect', kind: 'manifest', status: 'up-to-date' });\n\t\t\t\t} else {\n\t\t\t\t\tprintInfo('Manifest is up to date. Use --force to re-scan.');\n\t\t\t\t}\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\t\tconst analysis = await analyzeDomain(entitiesDir);\n\t\tconst transitiveSuggestions = suggestTransitiveRelationships(analysis.graph);\n\t\tconst existing = readManifest(ctx.cwd);\n\t\tconst manifest = await buildManifest(\n\t\t\tanalysis,\n\t\t\ttransitiveSuggestions,\n\t\t\tentitiesDir,\n\t\t\texisting\n\t\t);\n\t\twriteManifest(ctx.cwd, manifest);\n\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({\n\t\t\t\tcommand: 'project inspect',\n\t\t\t\tkind: 'manifest',\n\t\t\t\tstatistics: manifest.statistics,\n\t\t\t\tsuggestions: manifest.suggestions,\n\t\t\t});\n\t\t\treturn 0;\n\t\t}\n\n\t\tprintSuccess(`manifest updated → ${getManifestDir()}/manifest.json`);\n\t\tconsole.log(` entities: ${manifest.statistics.totalEntities}`);\n\t\tconsole.log(` relationships: ${manifest.statistics.totalRelationships}`);\n\t\tconsole.log(` fields: ${manifest.statistics.totalFields}`);\n\t\tconst pending = manifest.suggestions.transitive.filter((s) => s.status === 'pending');\n\t\tif (pending.length > 0) {\n\t\t\tprintInfo(\n\t\t\t\t`${pending.length} pending suggestion${pending.length === 1 ? '' : 's'} — run ${theme.system(\n\t\t\t\t\t'codegen project inspect --kind suggestions'\n\t\t\t\t)}`\n\t\t\t);\n\t\t}\n\t\treturn 0;\n\t}\n\n\tprivate async runSuggestions(ctx: Context): Promise<number> {\n\t\tif (this.acceptAll) {\n\t\t\tconst n = updateAllSuggestionStatus(ctx.cwd, 'accepted');\n\t\t\tif (isJsonMode()) {\n\t\t\t\tprintJson({ command: 'project inspect', kind: 'suggestions', acceptedAll: n });\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (n > 0) printSuccess(`accepted ${n} suggestion${n === 1 ? '' : 's'}`);\n\t\t\telse printInfo('No pending suggestions.');\n\t\t\treturn 0;\n\t\t}\n\t\tif (this.skipAll) {\n\t\t\tconst n = updateAllSuggestionStatus(ctx.cwd, 'skipped');\n\t\t\tif (isJsonMode()) {\n\t\t\t\tprintJson({ command: 'project inspect', kind: 'suggestions', skippedAll: n });\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (n > 0) printSuccess(`skipped ${n} suggestion${n === 1 ? '' : 's'}`);\n\t\t\telse printInfo('No pending suggestions.');\n\t\t\treturn 0;\n\t\t}\n\t\tif (this.accept) {\n\t\t\tconst ok = updateSuggestionStatus(ctx.cwd, this.accept, 'accepted');\n\t\t\tif (!ok) {\n\t\t\t\tprintError(`Suggestion not found: ${this.accept}`);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tprintSuccess(`accepted ${this.accept}`);\n\t\t\treturn 0;\n\t\t}\n\t\tif (this.skip) {\n\t\t\tconst ok = updateSuggestionStatus(ctx.cwd, this.skip, 'skipped');\n\t\t\tif (!ok) {\n\t\t\t\tprintError(`Suggestion not found: ${this.skip}`);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tprintSuccess(`skipped ${this.skip}`);\n\t\t\treturn 0;\n\t\t}\n\n\t\tconst pending = getPendingSuggestions(ctx.cwd);\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({ command: 'project inspect', kind: 'suggestions', pending });\n\t\t\treturn 0;\n\t\t}\n\t\tif (pending.length === 0) {\n\t\t\tprintInfo('No pending suggestions.');\n\t\t\treturn 0;\n\t\t}\n\t\tconsole.log(theme.system(`${pending.length} pending suggestions:`));\n\t\tfor (const s of pending) {\n\t\t\tconsole.log('');\n\t\t\tconsole.log(` ${theme.muted(s.id)} ${s.source} → ${s.target} (${s.suggestedName})`);\n\t\t}\n\t\treturn 0;\n\t}\n}\n\n// Local stats console formatter — avoids pulling in src/cli.ts. Keeps the\n// legacy look-and-feel for the inspect command.\nfunction formatStatsConsole(result: {\n\tstatistics: {\n\t\ttotalEntities: number;\n\t\ttotalFields: number;\n\t\ttotalRelationships: number;\n\t\taverageFieldsPerEntity: number;\n\t\tfieldsByType: Record<string, number>;\n\t\trelationshipsByType: Record<string, number>;\n\t};\n}): string {\n\tconst lines: string[] = [];\n\tlines.push('');\n\tlines.push(theme.system('Domain Statistics'));\n\tlines.push('');\n\tlines.push(` Entities: ${result.statistics.totalEntities}`);\n\tlines.push(\n\t\t` Fields: ${result.statistics.totalFields} (avg ${result.statistics.averageFieldsPerEntity.toFixed(1)}/entity)`\n\t);\n\tlines.push(` Relationships: ${result.statistics.totalRelationships}`);\n\tlines.push('');\n\tlines.push(' Field types:');\n\tfor (const [type, count] of Object.entries(result.statistics.fieldsByType).sort(\n\t\t(a, b) => b[1] - a[1]\n\t)) {\n\t\tlines.push(` ${type.padEnd(12)} ${count}`);\n\t}\n\tif (result.statistics.totalRelationships > 0) {\n\t\tlines.push('');\n\t\tlines.push(' Relationship types:');\n\t\tfor (const [type, count] of Object.entries(result.statistics.relationshipsByType).sort(\n\t\t\t(a, b) => b[1] - a[1]\n\t\t)) {\n\t\t\tlines.push(` ${type.padEnd(12)} ${count}`);\n\t\t}\n\t}\n\tlines.push('');\n\treturn lines.join('\\n');\n}\n\n\n// ---------------------------------------------------------------------------\n// ProjectGraphCommand\n// ---------------------------------------------------------------------------\n\nexport class ProjectGraphCommand extends Command {\n\tstatic paths = [['project', 'graph']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'Visualize the entity-relationship graph in a browser',\n\t\texamples: [\n\t\t\t['Open interactive graph viewer', 'codegen project graph'],\n\t\t\t['Export graph as JSON', 'codegen project graph --json'],\n\t\t\t['Write graph JSON to file', 'codegen project graph --output graph.json'],\n\t\t],\n\t});\n\n\tdir = Option.String({ required: false });\n\toutput = Option.String('--output,-o', { required: false });\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json) setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tconfigPath: this.configPath,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: true,\n\t\t});\n\n\t\tconst entitiesDir = this.dir\n\t\t\t? path.resolve(ctx.cwd, this.dir)\n\t\t\t: ctx.entitiesDir ?? path.resolve(ctx.cwd, 'entities');\n\n\t\tif (!fs.existsSync(entitiesDir)) {\n\t\t\tprintError(`Entity directory not found: ${entitiesDir}`);\n\t\t\treturn 1;\n\t\t}\n\n\t\t// Relationships dir: check alongside entities, then as subdirectory, then at cwd level\n\t\tconst relCandidates = [\n\t\t\tpath.resolve(path.dirname(entitiesDir), 'relationships'),\n\t\t\tpath.resolve(entitiesDir, 'relationships'),\n\t\t\tpath.resolve(ctx.cwd, 'relationships'),\n\t\t];\n\t\tconst relationshipsDir = relCandidates.find((d) => fs.existsSync(d));\n\n\t\tconst result = await analyzeDomain(entitiesDir, relationshipsDir);\n\t\tconst serialized = serializeDomainGraph(result.graph);\n\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({\n\t\t\t\tcommand: 'project graph',\n\t\t\t\tentities: result.entities.length,\n\t\t\t\trelationshipDefinitions: result.relationshipDefinitions.length,\n\t\t\t\tedges: result.graph.edges.length,\n\t\t\t\tgraph: serialized,\n\t\t\t});\n\t\t\treturn 0;\n\t\t}\n\n\t\tif (this.output) {\n\t\t\tconst outPath = path.resolve(ctx.cwd, this.output);\n\t\t\tfs.writeFileSync(outPath, JSON.stringify(serialized, null, 2));\n\t\t\tprintSuccess(`Graph written to ${outPath}`);\n\t\t\tprintInfo(`${result.entities.length} entities, ${result.relationshipDefinitions.length} relationships, ${result.graph.edges.length} edges`);\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Write to temp file and provide viewer instructions\n\t\tconst os = await import('node:os');\n\t\tconst tmpDir = fs.mkdtempSync(path.join(os.default.tmpdir(), 'codegen-graph-'));\n\t\tconst graphPath = path.join(tmpDir, 'graph.json');\n\t\tfs.writeFileSync(graphPath, JSON.stringify(serialized, null, 2));\n\n\t\tconst viewerDir = path.resolve(import.meta.dirname, '..', '..', '..', 'tools', 'schema-graph-viewer');\n\t\tconst viewerDist = path.join(viewerDir, 'dist', 'index.html');\n\n\t\tif (fs.existsSync(viewerDist)) {\n\t\t\tfs.copyFileSync(graphPath, path.join(viewerDir, 'dist', 'graph.json'));\n\t\t\tprintSuccess('Graph exported');\n\t\t\tprintInfo(`${result.entities.length} entities, ${result.relationshipDefinitions.length} relationships, ${result.graph.edges.length} edges`);\n\t\t\tprintInfo(`Graph JSON: ${graphPath}`);\n\t\t\tprintInfo(`Open the viewer: cd ${viewerDir} && npx vite preview`);\n\t\t} else {\n\t\t\tprintSuccess('Graph exported');\n\t\t\tprintInfo(`${result.entities.length} entities, ${result.relationshipDefinitions.length} relationships, ${result.graph.edges.length} edges`);\n\t\t\tprintInfo(`Graph JSON: ${graphPath}`);\n\t\t\tprintInfo(`To view: cd ${viewerDir} && bun install && bun run dev`);\n\t\t}\n\n\t\treturn 0;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// NounModule default export\n// ---------------------------------------------------------------------------\n\nconst projectNoun: NounModule = {\n\tname: 'project',\n\tcommandClasses: [\n\t\tProjectInitCommand,\n\t\tProjectScanCommand,\n\t\tProjectConfigCommand,\n\t\tProjectInspectCommand,\n\t\tProjectGraphCommand,\n\t] as CommandClass[],\n\tsummary,\n\thints,\n};\n\nexport default projectNoun;\n","/**\n * Dev noun — codegen dev / dev up / dev down / dev status / dev logs / dev restart\n *\n * Manages the development environment for a generated NestJS + Drizzle project:\n * Docker services (Postgres + Redis), schema migrations, and the NestJS app.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { execSync, spawn, spawnSync } from 'node:child_process';\nimport { Command, Option } from 'clipanion';\nimport type { CommandClass } from 'clipanion';\n\nimport { loadContext, type Context } from '../shared/context.js';\nimport { theme } from '../ui/theme.js';\nimport { icons } from '../ui/icons.js';\nimport { printError, printInfo, printSuccess, printWarning } from '../ui/output.js';\nimport { isJsonMode, printJson, setJsonMode } from '../ui/json.js';\nimport { renderPane, type PaneOutput } from '../ui/pane.js';\nimport { renderHints, type Hint } from '../ui/hints.js';\nimport type { NounModule } from '../noun-module.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_APP_PORT = 3000;\nconst DEFAULT_PG_PORT = 5433;\nconst DEFAULT_REDIS_PORT = 6380;\nconst COMPOSE_FILE = 'docker-compose.dev.yml';\nconst PID_FILE = '.dev-app.pid';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction runCmd(cmd: string, cwd: string, opts?: { silent?: boolean }): {\n\tok: boolean;\n\tstdout: string;\n\tstderr: string;\n\tcode: number;\n} {\n\tconst parts = cmd.split(' ');\n\tconst r = spawnSync(parts[0], parts.slice(1), {\n\t\tcwd,\n\t\tencoding: 'utf-8',\n\t\ttimeout: 30_000,\n\t});\n\treturn {\n\t\tok: r.status === 0,\n\t\tstdout: r.stdout ?? '',\n\t\tstderr: r.stderr ?? '',\n\t\tcode: r.status ?? 1,\n\t};\n}\n\nfunction getAppPort(ctx: Context): number {\n\tconst env = (ctx.config as Record<string, unknown> | null)?.dev as\n\t\t| Record<string, unknown>\n\t\t| undefined;\n\treturn Number(env?.port ?? process.env.PORT ?? DEFAULT_APP_PORT);\n}\n\nfunction getPgPort(_ctx: Context): number {\n\treturn Number(process.env.DEV_PG_PORT ?? DEFAULT_PG_PORT);\n}\n\nfunction getRedisPort(_ctx: Context): number {\n\treturn Number(process.env.DEV_REDIS_PORT ?? DEFAULT_REDIS_PORT);\n}\n\nfunction composeFilePath(cwd: string): string {\n\t// Check for dev compose first, then fall back to root compose\n\tconst devPath = path.join(cwd, COMPOSE_FILE);\n\tif (fs.existsSync(devPath)) return devPath;\n\tconst rootPath = path.join(cwd, 'docker-compose.yml');\n\tif (fs.existsSync(rootPath)) return rootPath;\n\treturn devPath; // will be created\n}\n\nfunction pidFilePath(cwd: string): string {\n\treturn path.join(cwd, PID_FILE);\n}\n\nfunction readAppPid(cwd: string): number | null {\n\tconst p = pidFilePath(cwd);\n\tif (!fs.existsSync(p)) return null;\n\tconst pid = parseInt(fs.readFileSync(p, 'utf-8').trim(), 10);\n\tif (isNaN(pid)) return null;\n\t// Check if process is alive\n\ttry {\n\t\tprocess.kill(pid, 0);\n\t\treturn pid;\n\t} catch {\n\t\t// Process dead — clean up stale PID file\n\t\tfs.rmSync(p, { force: true });\n\t\treturn null;\n\t}\n}\n\nfunction writeAppPid(cwd: string, pid: number): void {\n\tfs.writeFileSync(pidFilePath(cwd), String(pid));\n}\n\nfunction clearAppPid(cwd: string): void {\n\tfs.rmSync(pidFilePath(cwd), { force: true });\n}\n\ninterface ServiceStatus {\n\tname: string;\n\thost: string;\n\tport: number;\n\thealthy: boolean;\n\tpid?: number;\n}\n\nfunction checkPostgres(cwd: string, port: number): ServiceStatus {\n\tconst r = runCmd(`docker exec codegen-dev-postgres pg_isready -U postgres`, cwd, {\n\t\tsilent: true,\n\t});\n\treturn {\n\t\tname: 'postgres',\n\t\thost: 'localhost',\n\t\tport,\n\t\thealthy: r.ok,\n\t};\n}\n\nfunction checkRedis(cwd: string, port: number): ServiceStatus {\n\tconst r = runCmd(`docker exec codegen-dev-redis redis-cli ping`, cwd, { silent: true });\n\treturn {\n\t\tname: 'redis',\n\t\thost: 'localhost',\n\t\tport,\n\t\thealthy: r.ok && r.stdout.trim() === 'PONG',\n\t};\n}\n\nfunction checkApp(cwd: string, port: number): ServiceStatus {\n\tconst pid = readAppPid(cwd);\n\tif (!pid) return { name: 'app', host: 'localhost', port, healthy: false };\n\n\t// Quick HTTP check\n\tconst r = runCmd(\n\t\t`curl -s -o /dev/null -w %{http_code} http://localhost:${port}/`,\n\t\tcwd,\n\t\t{ silent: true },\n\t);\n\tconst code = parseInt(r.stdout.trim(), 10);\n\treturn {\n\t\tname: 'app',\n\t\thost: 'localhost',\n\t\tport,\n\t\thealthy: code >= 200 && code < 500,\n\t\tpid,\n\t};\n}\n\nfunction listEntityNames(ctx: Context): string[] {\n\tif (!ctx.entitiesDir || !fs.existsSync(ctx.entitiesDir)) return [];\n\treturn fs\n\t\t.readdirSync(ctx.entitiesDir)\n\t\t.filter((f) => f.endsWith('.yaml') || f.endsWith('.yml'))\n\t\t.map((f) => f.replace(/\\.ya?ml$/, ''));\n}\n\nfunction formatServiceLine(svc: ServiceStatus): string {\n\tconst icon = svc.healthy ? theme.success(icons.check) : theme.error(icons.error);\n\tconst status = svc.healthy ? theme.success('healthy') : theme.error('stopped');\n\tconst pidStr = svc.pid ? ` PID ${svc.pid}` : '';\n\treturn `${icon} ${svc.name.padEnd(12)} ${theme.muted(`${svc.host}:${svc.port}`)} ${status}${pidStr}`;\n}\n\nfunction ensureComposeFile(cwd: string, pgPort: number, redisPort: number): string {\n\tconst composePath = path.join(cwd, COMPOSE_FILE);\n\tif (fs.existsSync(composePath)) return composePath;\n\n\tconst content = `# Auto-generated by codegen dev\n# Ports offset from defaults to avoid conflicts with other local services.\nservices:\n postgres:\n image: postgres:16-alpine\n container_name: codegen-dev-postgres\n environment:\n POSTGRES_USER: postgres\n POSTGRES_PASSWORD: postgres\n POSTGRES_DB: codegen_dev\n ports:\n - \"${pgPort}:5432\"\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgres -d codegen_dev\"]\n interval: 2s\n timeout: 2s\n retries: 20\n volumes:\n - codegen-dev-pgdata:/var/lib/postgresql/data\n\n redis:\n image: redis:7-alpine\n container_name: codegen-dev-redis\n ports:\n - \"${redisPort}:6379\"\n healthcheck:\n test: [\"CMD\", \"redis-cli\", \"ping\"]\n interval: 2s\n timeout: 2s\n retries: 20\n\nvolumes:\n codegen-dev-pgdata:\n`;\n\tfs.writeFileSync(composePath, content);\n\treturn composePath;\n}\n\n// ---------------------------------------------------------------------------\n// DevUpCommand\n// ---------------------------------------------------------------------------\n\nexport class DevUpCommand extends Command {\n\tstatic paths = [['dev', 'up']];\n\tstatic usage = Command.Usage({\n\t\tdescription:\n\t\t\t'Start Docker services (Postgres + Redis), run migrations, start the NestJS app',\n\t\texamples: [\n\t\t\t['Start everything', 'codegen dev up'],\n\t\t\t['Skip app start (services only)', 'codegen dev up --no-app'],\n\t\t],\n\t});\n\n\tnoApp = Option.Boolean('--no-app', false);\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json) setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tconfigPath: this.configPath,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: true,\n\t\t});\n\n\t\tconst pgPort = getPgPort(ctx);\n\t\tconst redisPort = getRedisPort(ctx);\n\t\tconst appPort = getAppPort(ctx);\n\n\t\t// 1. Ensure docker-compose file exists\n\t\tconst composePath = ensureComposeFile(ctx.cwd, pgPort, redisPort);\n\n\t\t// 2. Start Docker services\n\t\tif (!isJsonMode()) printInfo('starting Docker services...');\n\t\tconst composeUp = runCmd(\n\t\t\t`docker compose -f ${composePath} up -d --wait`,\n\t\t\tctx.cwd,\n\t\t);\n\t\tif (!composeUp.ok) {\n\t\t\tprintError(`docker compose failed: ${composeUp.stderr.slice(0, 300)}`);\n\t\t\treturn 1;\n\t\t}\n\t\tif (!isJsonMode()) printSuccess('Docker services running');\n\n\t\t// 3. Wait for health checks\n\t\tlet pgReady = false;\n\t\tlet redisReady = false;\n\t\tfor (let i = 0; i < 15; i++) {\n\t\t\tif (!pgReady) pgReady = checkPostgres(ctx.cwd, pgPort).healthy;\n\t\t\tif (!redisReady) redisReady = checkRedis(ctx.cwd, redisPort).healthy;\n\t\t\tif (pgReady && redisReady) break;\n\t\t\tspawnSync('sleep', ['1']);\n\t\t}\n\n\t\tif (!pgReady) printWarning('postgres did not become healthy in time');\n\t\tif (!redisReady) printWarning('redis did not become healthy in time');\n\n\t\t// 4. Run schema push/migration if drizzle config exists\n\t\tconst drizzleConfig = ['drizzle.config.ts', 'drizzle.config.js'].find((f) =>\n\t\t\tfs.existsSync(path.join(ctx.cwd, f)),\n\t\t);\n\t\tif (drizzleConfig) {\n\t\t\tif (!isJsonMode()) printInfo('pushing database schema...');\n\t\t\tconst dbUrl = `postgres://postgres:postgres@localhost:${pgPort}/codegen_dev`;\n\t\t\tconst push = runCmd(`bunx drizzle-kit push --config ${drizzleConfig}`, ctx.cwd);\n\t\t\tif (!push.ok) {\n\t\t\t\tprintWarning(`schema push may have failed: ${push.stderr.slice(0, 200)}`);\n\t\t\t} else {\n\t\t\t\tif (!isJsonMode()) printSuccess('schema pushed');\n\t\t\t}\n\t\t}\n\n\t\t// 5. Start the app (unless --no-app)\n\t\tif (!this.noApp) {\n\t\t\tconst existingPid = readAppPid(ctx.cwd);\n\t\t\tif (existingPid) {\n\t\t\t\tif (!isJsonMode()) printInfo(`app already running (PID ${existingPid})`);\n\t\t\t} else {\n\t\t\t\tif (!isJsonMode()) printInfo('starting NestJS app...');\n\t\t\t\tconst dbUrl = `postgres://postgres:postgres@localhost:${pgPort}/codegen_dev`;\n\t\t\t\tconst redisUrl = `redis://localhost:${redisPort}`;\n\t\t\t\tconst logFile = path.join(ctx.cwd, '.dev-app.log');\n\t\t\t\tconst logFd = fs.openSync(logFile, 'a');\n\n\t\t\t\tconst child = spawn('bun', ['src/main.ts'], {\n\t\t\t\t\tcwd: ctx.cwd,\n\t\t\t\t\tdetached: true,\n\t\t\t\t\tstdio: ['ignore', logFd, logFd],\n\t\t\t\t\tenv: {\n\t\t\t\t\t\t...process.env,\n\t\t\t\t\t\tDATABASE_URL: dbUrl,\n\t\t\t\t\t\tREDIS_URL: redisUrl,\n\t\t\t\t\t\tPORT: String(appPort),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tchild.unref();\n\t\t\t\tfs.closeSync(logFd);\n\n\t\t\t\tif (child.pid) {\n\t\t\t\t\twriteAppPid(ctx.cwd, child.pid);\n\t\t\t\t\t// Wait briefly for app to start\n\t\t\t\t\tspawnSync('sleep', ['2']);\n\t\t\t\t\tconst appStatus = checkApp(ctx.cwd, appPort);\n\t\t\t\t\tif (appStatus.healthy) {\n\t\t\t\t\t\tif (!isJsonMode()) printSuccess(`app running on port ${appPort} (PID ${child.pid})`);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (!isJsonMode())\n\t\t\t\t\t\t\tprintWarning(\n\t\t\t\t\t\t\t\t`app started (PID ${child.pid}) but not responding yet — check logs with: codegen dev logs`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 6. Show status\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({\n\t\t\t\tcommand: 'dev up',\n\t\t\t\tpostgres: { port: pgPort, healthy: pgReady },\n\t\t\t\tredis: { port: redisPort, healthy: redisReady },\n\t\t\t\tapp: this.noApp ? null : { port: appPort, pid: readAppPid(ctx.cwd) },\n\t\t\t});\n\t\t} else {\n\t\t\tconsole.log('');\n\t\t\trenderDevStatus(ctx);\n\t\t}\n\n\t\treturn 0;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// DevDownCommand\n// ---------------------------------------------------------------------------\n\nexport class DevDownCommand extends Command {\n\tstatic paths = [['dev', 'down']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'Stop Docker services and the NestJS app',\n\t});\n\n\tvolumes = Option.Boolean('--volumes,-v', false);\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json) setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tconfigPath: this.configPath,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: true,\n\t\t});\n\n\t\t// Stop app\n\t\tconst pid = readAppPid(ctx.cwd);\n\t\tif (pid) {\n\t\t\ttry {\n\t\t\t\tprocess.kill(pid, 'SIGTERM');\n\t\t\t\tif (!isJsonMode()) printSuccess(`stopped app (PID ${pid})`);\n\t\t\t} catch {\n\t\t\t\tif (!isJsonMode()) printWarning(`app process ${pid} already gone`);\n\t\t\t}\n\t\t\tclearAppPid(ctx.cwd);\n\t\t}\n\n\t\t// Stop Docker\n\t\tconst composePath = composeFilePath(ctx.cwd);\n\t\tconst volFlag = this.volumes ? '-v' : '';\n\t\tconst r = runCmd(\n\t\t\t`docker compose -f ${composePath} down ${volFlag}`.trim(),\n\t\t\tctx.cwd,\n\t\t);\n\t\tif (r.ok) {\n\t\t\tif (!isJsonMode()) printSuccess('Docker services stopped');\n\t\t} else {\n\t\t\tprintWarning(`docker compose down: ${r.stderr.slice(0, 200)}`);\n\t\t}\n\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({ command: 'dev down', ok: true });\n\t\t}\n\t\treturn 0;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// DevStatusCommand\n// ---------------------------------------------------------------------------\n\nexport class DevStatusCommand extends Command {\n\tstatic paths = [['dev', 'status']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'Show status of Docker services and the NestJS app',\n\t});\n\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json) setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tconfigPath: this.configPath,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: true,\n\t\t});\n\n\t\tif (isJsonMode()) {\n\t\t\tconst pgPort = getPgPort(ctx);\n\t\t\tconst redisPort = getRedisPort(ctx);\n\t\t\tconst appPort = getAppPort(ctx);\n\t\t\tprintJson({\n\t\t\t\tcommand: 'dev status',\n\t\t\t\tservices: {\n\t\t\t\t\tpostgres: checkPostgres(ctx.cwd, pgPort),\n\t\t\t\t\tredis: checkRedis(ctx.cwd, redisPort),\n\t\t\t\t\tapp: checkApp(ctx.cwd, appPort),\n\t\t\t\t},\n\t\t\t\tentities: listEntityNames(ctx),\n\t\t\t});\n\t\t\treturn 0;\n\t\t}\n\n\t\trenderDevStatus(ctx);\n\t\treturn 0;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// DevLogsCommand\n// ---------------------------------------------------------------------------\n\nexport class DevLogsCommand extends Command {\n\tstatic paths = [['dev', 'logs']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'Tail application and Docker service logs',\n\t\texamples: [\n\t\t\t['Tail app logs', 'codegen dev logs'],\n\t\t\t['Tail Docker logs', 'codegen dev logs --docker'],\n\t\t\t['Show last N lines', 'codegen dev logs --tail 50'],\n\t\t],\n\t});\n\n\tdocker = Option.Boolean('--docker', false);\n\ttail = Option.String('--tail', '30');\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json) setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tconfigPath: this.configPath,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: true,\n\t\t});\n\n\t\tif (this.docker) {\n\t\t\tconst composePath = composeFilePath(ctx.cwd);\n\t\t\ttry {\n\t\t\t\texecSync(`docker compose -f ${composePath} logs --tail ${this.tail}`, {\n\t\t\t\t\tcwd: ctx.cwd,\n\t\t\t\t\tstdio: 'inherit',\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\tprintWarning('no Docker logs available');\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\n\t\t// App logs\n\t\tconst logFile = path.join(ctx.cwd, '.dev-app.log');\n\t\tif (!fs.existsSync(logFile)) {\n\t\t\tprintInfo('no app logs found — is the app running?');\n\t\t\treturn 0;\n\t\t}\n\n\t\ttry {\n\t\t\texecSync(`tail -n ${this.tail} ${logFile}`, { stdio: 'inherit' });\n\t\t} catch {\n\t\t\tprintWarning('could not read app logs');\n\t\t}\n\t\treturn 0;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// DevRestartCommand\n// ---------------------------------------------------------------------------\n\nexport class DevRestartCommand extends Command {\n\tstatic paths = [['dev', 'restart']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'Restart the NestJS app (keep Docker services running)',\n\t});\n\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json) setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tconfigPath: this.configPath,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: true,\n\t\t});\n\n\t\tconst appPort = getAppPort(ctx);\n\t\tconst pgPort = getPgPort(ctx);\n\t\tconst redisPort = getRedisPort(ctx);\n\n\t\t// Kill existing app\n\t\tconst pid = readAppPid(ctx.cwd);\n\t\tif (pid) {\n\t\t\ttry {\n\t\t\t\tprocess.kill(pid, 'SIGTERM');\n\t\t\t\tif (!isJsonMode()) printInfo(`stopped app (PID ${pid})`);\n\t\t\t} catch {\n\t\t\t\t// already gone\n\t\t\t}\n\t\t\tclearAppPid(ctx.cwd);\n\t\t}\n\n\t\t// Brief pause for port release\n\t\tspawnSync('sleep', ['1']);\n\n\t\t// Restart\n\t\tconst dbUrl = `postgres://postgres:postgres@localhost:${pgPort}/codegen_dev`;\n\t\tconst redisUrl = `redis://localhost:${redisPort}`;\n\t\tconst logFile = path.join(ctx.cwd, '.dev-app.log');\n\t\tconst logFd = fs.openSync(logFile, 'a');\n\n\t\tconst child = spawn('bun', ['src/main.ts'], {\n\t\t\tcwd: ctx.cwd,\n\t\t\tdetached: true,\n\t\t\tstdio: ['ignore', logFd, logFd],\n\t\t\tenv: {\n\t\t\t\t...process.env,\n\t\t\t\tDATABASE_URL: dbUrl,\n\t\t\t\tREDIS_URL: redisUrl,\n\t\t\t\tPORT: String(appPort),\n\t\t\t},\n\t\t});\n\t\tchild.unref();\n\t\tfs.closeSync(logFd);\n\n\t\tif (child.pid) {\n\t\t\twriteAppPid(ctx.cwd, child.pid);\n\t\t\tspawnSync('sleep', ['2']);\n\t\t\tconst status = checkApp(ctx.cwd, appPort);\n\t\t\tif (status.healthy) {\n\t\t\t\tif (!isJsonMode()) printSuccess(`app restarted on port ${appPort} (PID ${child.pid})`);\n\t\t\t} else {\n\t\t\t\tif (!isJsonMode())\n\t\t\t\t\tprintWarning(`app restarted (PID ${child.pid}) but not responding yet`);\n\t\t\t}\n\t\t}\n\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({ command: 'dev restart', pid: child.pid, port: appPort });\n\t\t}\n\n\t\treturn 0;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Shared dashboard renderer\n// ---------------------------------------------------------------------------\n\nfunction renderDevStatus(ctx: Context): void {\n\tconst pgPort = getPgPort(ctx);\n\tconst redisPort = getRedisPort(ctx);\n\tconst appPort = getAppPort(ctx);\n\n\tconst pg = checkPostgres(ctx.cwd, pgPort);\n\tconst redis = checkRedis(ctx.cwd, redisPort);\n\tconst app = checkApp(ctx.cwd, appPort);\n\tconst entities = listEntityNames(ctx);\n\n\tconst body: string[] = [\n\t\t'Services:',\n\t\t` ${formatServiceLine(pg)}`,\n\t\t` ${formatServiceLine(redis)}`,\n\t\t` ${formatServiceLine(app)}`,\n\t\t'',\n\t\t`Entities: ${entities.length > 0 ? `${entities.length} generated (${entities.join(', ')})` : 'none'}`,\n\t];\n\n\t// Check for endpoints if app is healthy\n\tif (app.healthy && entities.length > 0) {\n\t\tbody.push('');\n\t\tbody.push('Endpoints:');\n\t\tfor (const name of entities) {\n\t\t\tconst plural = name.endsWith('y')\n\t\t\t\t? name.slice(0, -1) + 'ies'\n\t\t\t\t: name.endsWith('s')\n\t\t\t\t\t? name + 'es'\n\t\t\t\t\t: name + 's';\n\t\t\tconst r = runCmd(\n\t\t\t\t`curl -s -o /dev/null -w %{http_code} http://localhost:${appPort}/${plural}`,\n\t\t\t\tctx.cwd,\n\t\t\t\t{ silent: true },\n\t\t\t);\n\t\t\tconst code = r.stdout.trim();\n\t\t\tconst ok = code.startsWith('2') || code.startsWith('3');\n\t\t\tconst icon = ok ? theme.success(icons.check) : theme.error(icons.error);\n\t\t\tbody.push(\n\t\t\t\t` ${icon} GET /${plural.padEnd(20)} ${ok ? theme.success(`${code} OK`) : theme.error(code || 'ERR')}`,\n\t\t\t);\n\t\t}\n\t}\n\n\trenderPane({ title: 'dev environment', body });\n\trenderHints([\n\t\t{ command: 'codegen dev logs', description: 'Tail application logs' },\n\t\t{ command: 'codegen dev logs --docker', description: 'Tail Docker service logs' },\n\t\t{ command: 'codegen dev restart', description: 'Restart the NestJS app' },\n\t\t{ command: 'codegen dev down', description: 'Stop everything' },\n\t\t{ command: '/dev-check', description: 'Run full health check with browser verification' },\n\t\t{ command: '/dev-test', description: 'Run test suite + endpoint verification' },\n\t]);\n}\n\n// ---------------------------------------------------------------------------\n// summary + hints for NounModule\n// ---------------------------------------------------------------------------\n\nasync function summary(ctx: Context): Promise<PaneOutput> {\n\tconst pgPort = getPgPort(ctx);\n\tconst redisPort = getRedisPort(ctx);\n\tconst appPort = getAppPort(ctx);\n\n\tconst pg = checkPostgres(ctx.cwd, pgPort);\n\tconst redis = checkRedis(ctx.cwd, redisPort);\n\tconst app = checkApp(ctx.cwd, appPort);\n\tconst entities = listEntityNames(ctx);\n\n\tconst running = [pg, redis, app].filter((s) => s.healthy).length;\n\tconst total = 3;\n\n\tconst body: string[] = [\n\t\t'Services:',\n\t\t` ${formatServiceLine(pg)}`,\n\t\t` ${formatServiceLine(redis)}`,\n\t\t` ${formatServiceLine(app)}`,\n\t\t'',\n\t\t`Entities: ${entities.length > 0 ? `${entities.length} (${entities.join(', ')})` : 'none'}`,\n\t];\n\n\treturn {\n\t\ttitle: 'dev environment',\n\t\tbody,\n\t\tfooter: `${running}/${total} services healthy`,\n\t};\n}\n\nasync function hints(ctx: Context): Promise<Hint[]> {\n\tconst app = checkApp(ctx.cwd, getAppPort(ctx));\n\tif (!app.healthy) {\n\t\treturn [\n\t\t\t{ command: 'codegen dev up', description: 'Start dev environment' },\n\t\t];\n\t}\n\treturn [\n\t\t{ command: 'codegen dev status', description: 'Show full status dashboard' },\n\t\t{ command: 'codegen dev logs', description: 'Tail application logs' },\n\t\t{ command: 'codegen dev restart', description: 'Restart the NestJS app' },\n\t\t{ command: 'codegen dev down', description: 'Stop everything' },\n\t];\n}\n\n// ---------------------------------------------------------------------------\n// NounModule default export\n// ---------------------------------------------------------------------------\n\nconst devNoun: NounModule = {\n\tname: 'dev',\n\tcommandClasses: [\n\t\tDevUpCommand,\n\t\tDevDownCommand,\n\t\tDevStatusCommand,\n\t\tDevLogsCommand,\n\t\tDevRestartCommand,\n\t] as CommandClass[],\n\tsummary,\n\thints,\n};\n\nexport default devNoun;\n","/**\n * Relationship noun — codegen relationship new / relationship list\n *\n * Generates code for first-class relationship definitions (junction tables\n * between core entities). Mirrors the entity noun but delegates to the\n * relationship template set.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { Command, Option } from 'clipanion';\nimport type { CommandClass } from 'clipanion';\n\nimport { loadRelationshipFromYaml, detectYamlType } from '../../utils/yaml-loader.js';\n\nimport { loadContext, type Context } from '../shared/context.js';\nimport { invokeRelationshipNew } from '../shared/hygen.js';\nimport { checkGitSafety } from '../shared/git-safety.js';\n\nimport { theme } from '../ui/theme.js';\nimport { icons } from '../ui/icons.js';\nimport { printError, printInfo, printSuccess, printWarning } from '../ui/output.js';\nimport { isJsonMode, printJson, setJsonMode } from '../ui/json.js';\nimport type { PaneOutput } from '../ui/pane.js';\nimport type { Hint } from '../ui/hints.js';\nimport type { NounModule } from '../noun-module.js';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction listRelationshipYamls(dir: string): string[] {\n\tif (!fs.existsSync(dir)) return [];\n\treturn fs\n\t\t.readdirSync(dir)\n\t\t.filter((f) => f.endsWith('.yaml') || f.endsWith('.yml'))\n\t\t.filter((f) => {\n\t\t\t// Only include files that are actual relationship definitions\n\t\t\tconst fullPath = path.join(dir, f);\n\t\t\treturn detectYamlType(fullPath) === 'relationship';\n\t\t})\n\t\t.map((f) => path.join(dir, f));\n}\n\ninterface RelationshipSummaryRow {\n\tname: string;\n\tfrom: string;\n\tto: string;\n\ttypes: number;\n\ttemporal: boolean;\n\tsourced: boolean;\n\tfile: string;\n}\n\nfunction summarizeRelationshipFile(filePath: string): RelationshipSummaryRow | null {\n\tconst result = loadRelationshipFromYaml(filePath);\n\tif (!result.success) return null;\n\tconst def = result.definition;\n\tconst types = def.relationship.types\n\t\t? Array.isArray(def.relationship.types)\n\t\t\t? def.relationship.types.length\n\t\t\t: Object.keys(def.relationship.types).length\n\t\t: 0;\n\treturn {\n\t\tname: def.relationship.name,\n\t\tfrom: def.relationship.from,\n\t\tto: def.relationship.to,\n\t\ttypes,\n\t\ttemporal: def.relationship.temporal,\n\t\tsourced: def.relationship.sourced,\n\t\tfile: filePath,\n\t};\n}\n\nfunction padRight(s: string, n: number): string {\n\treturn s.length >= n ? s : s + ' '.repeat(n - s.length);\n}\n\n// ---------------------------------------------------------------------------\n// summary + hints\n// ---------------------------------------------------------------------------\n\nasync function summary(ctx: Context): Promise<PaneOutput> {\n\tconst relDir = path.resolve(ctx.cwd, 'relationships');\n\tconst files = listRelationshipYamls(relDir);\n\n\tif (files.length === 0) {\n\t\treturn {\n\t\t\ttitle: 'relationships',\n\t\t\tbody: [\n\t\t\t\t'No relationship definitions found.',\n\t\t\t\t'',\n\t\t\t\t`Create one at ${theme.system('relationships/<name>.yaml')} to get started.`,\n\t\t\t],\n\t\t};\n\t}\n\n\tconst rows = files\n\t\t.map(summarizeRelationshipFile)\n\t\t.filter((r): r is RelationshipSummaryRow => r !== null);\n\n\tconst nameCol = Math.max(4, ...rows.map((r) => r.name.length));\n\tconst endpointsCol = Math.max(9, ...rows.map((r) => `${r.from} → ${r.to}`.length));\n\n\tconst body = rows.map((r) => {\n\t\tconst endpoints = `${r.from} → ${r.to}`;\n\t\tconst flags = [\n\t\t\tr.types > 0 ? `${r.types} types` : '',\n\t\t\tr.temporal ? 'temporal' : '',\n\t\t\tr.sourced ? 'sourced' : '',\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.join(', ');\n\t\treturn `${theme.system(icons.bullet)} ${padRight(r.name, nameCol)} ${theme.muted(\n\t\t\tpadRight(endpoints, endpointsCol)\n\t\t)} ${theme.muted(flags)}`;\n\t});\n\n\treturn {\n\t\ttitle: 'relationships',\n\t\tbody,\n\t\tfooter: `${rows.length} relationships`,\n\t};\n}\n\nasync function hints(_ctx: Context): Promise<Hint[]> {\n\treturn [\n\t\t{ command: 'codegen relationship new <file>', description: 'Generate one relationship' },\n\t\t{ command: 'codegen relationship new --all', description: 'Generate all relationships' },\n\t\t{ command: 'codegen relationship list', description: 'List relationship definitions' },\n\t];\n}\n\n// ---------------------------------------------------------------------------\n// RelationshipNewCommand\n// ---------------------------------------------------------------------------\n\nexport class RelationshipNewCommand extends Command {\n\tstatic paths = [['relationship', 'new']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'Generate code for one or more relationships from YAML',\n\t\texamples: [\n\t\t\t['Generate a single relationship', 'codegen relationship new relationships/person_organization.yaml'],\n\t\t\t['Generate all relationships', 'codegen relationship new --all'],\n\t\t\t['Preview without writing', 'codegen relationship new relationships/person_organization.yaml --dry-run'],\n\t\t],\n\t});\n\n\tyaml = Option.String({ required: false });\n\tall = Option.Boolean('--all', false);\n\tdryRun = Option.Boolean('--dry-run', false);\n\tforce = Option.Boolean('--force', false);\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json) setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tconfigPath: this.configPath,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: true,\n\t\t});\n\n\t\tif (this.all && this.yaml) {\n\t\t\tprintError('Pass either a YAML path or --all, not both.');\n\t\t\treturn 2;\n\t\t}\n\n\t\tlet targets: string[] = [];\n\t\tif (this.all) {\n\t\t\tconst dir = path.resolve(ctx.cwd, 'relationships');\n\t\t\ttargets = listRelationshipYamls(dir);\n\t\t\tif (targets.length === 0) {\n\t\t\t\tprintError(`No relationship YAML files found in ${dir}`);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t} else if (this.yaml) {\n\t\t\ttargets = [path.resolve(ctx.cwd, this.yaml)];\n\t\t} else {\n\t\t\tprintError('Missing YAML path. Pass a file or --all.');\n\t\t\treturn 2;\n\t\t}\n\n\t\t// Pre-flight: validate each YAML.\n\t\tconst validated: Array<{ file: string; name: string }> = [];\n\t\tconst invalid: Array<{ file: string; message: string }> = [];\n\t\tfor (const file of targets) {\n\t\t\tconst result = loadRelationshipFromYaml(file);\n\t\t\tif (result.success) {\n\t\t\t\tvalidated.push({ file, name: result.definition.relationship.name });\n\t\t\t} else {\n\t\t\t\tinvalid.push({ file, message: result.error });\n\t\t\t}\n\t\t}\n\n\t\tif (invalid.length > 0) {\n\t\t\tfor (const i of invalid) {\n\t\t\t\tprintError(`${path.basename(i.file)} — ${i.message}`);\n\t\t\t}\n\t\t\tif (!isJsonMode()) return 1;\n\t\t}\n\n\t\t// Git safety\n\t\tif (!this.force) {\n\t\t\tconst gitCheck = checkGitSafety(['src'], ctx.cwd);\n\t\t\tif (gitCheck.inRepo && !gitCheck.clean) {\n\t\t\t\tprintWarning(\n\t\t\t\t\t`Uncommitted changes in ${gitCheck.dirty.length} files under src/. Pass --force to overwrite.`\n\t\t\t\t);\n\t\t\t\tif (!isJsonMode()) return 1;\n\t\t\t}\n\t\t}\n\n\t\tif (this.dryRun) {\n\t\t\tif (isJsonMode()) {\n\t\t\t\tprintJson({\n\t\t\t\t\tcommand: 'relationship new',\n\t\t\t\t\tdryRun: true,\n\t\t\t\t\trelationships: validated.map((v) => ({ name: v.name, file: v.file })),\n\t\t\t\t\ttotals: { planned: validated.length, invalid: invalid.length },\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tprintInfo(`Dry run — ${validated.length} relationships would be generated:`);\n\t\t\t\tfor (const v of validated) {\n\t\t\t\t\tconsole.log(` ${theme.muted(icons.arrow)} ${v.name} ${theme.muted(v.file)}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn invalid.length > 0 ? 1 : 0;\n\t\t}\n\n\t\t// Invoke Hygen for each validated target.\n\t\tconst succeeded: string[] = [];\n\t\tconst failed: Array<{ name: string; file: string; message: string }> = [\n\t\t\t...invalid.map((i) => ({ name: path.basename(i.file), file: i.file, message: i.message })),\n\t\t];\n\t\tfor (const v of validated) {\n\t\t\tif (!isJsonMode()) {\n\t\t\t\tprintInfo(`generating ${v.name}`);\n\t\t\t}\n\t\t\tconst res = invokeRelationshipNew(v.file, ctx.cwd);\n\t\t\tif (res.ok) {\n\t\t\t\tsucceeded.push(v.name);\n\t\t\t\tif (!isJsonMode()) printSuccess(`${v.name}`);\n\t\t\t} else {\n\t\t\t\tfailed.push({\n\t\t\t\t\tname: v.name,\n\t\t\t\t\tfile: v.file,\n\t\t\t\t\tmessage: res.stderr ?? 'Hygen invocation failed',\n\t\t\t\t});\n\t\t\t\tif (!isJsonMode()) printError(`${v.name} — ${res.stderr ?? 'failed'}`);\n\t\t\t}\n\t\t}\n\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({\n\t\t\t\tcommand: 'relationship new',\n\t\t\t\ttotals: {\n\t\t\t\t\tsucceeded: succeeded.length,\n\t\t\t\t\tfailed: failed.length,\n\t\t\t\t},\n\t\t\t\tsucceeded,\n\t\t\t\tfailed,\n\t\t\t});\n\t\t} else {\n\t\t\tconst total = validated.length + invalid.length;\n\t\t\tconsole.log('');\n\t\t\tif (failed.length === 0) {\n\t\t\t\tprintSuccess(`${total} relationships · ${succeeded.length} succeeded`);\n\t\t\t} else {\n\t\t\t\tprintWarning(\n\t\t\t\t\t`${total} relationships · ${succeeded.length} succeeded · ${failed.length} failed`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn failed.length === 0 ? 0 : 1;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// RelationshipListCommand\n// ---------------------------------------------------------------------------\n\nexport class RelationshipListCommand extends Command {\n\tstatic paths = [['relationship', 'list']];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'List defined relationships as a table',\n\t});\n\n\tjson = Option.Boolean('--json', false);\n\tcwd = Option.String('--cwd', { required: false });\n\tconfigPath = Option.String('--config', { required: false });\n\n\tasync execute(): Promise<number> {\n\t\tif (this.json) setJsonMode(true);\n\t\tconst ctx = await loadContext({\n\t\t\tcwd: this.cwd,\n\t\t\tconfigPath: this.configPath,\n\t\t\tjson: this.json,\n\t\t\tskipDetection: true,\n\t\t});\n\n\t\tconst relDir = path.resolve(ctx.cwd, 'relationships');\n\t\tconst files = listRelationshipYamls(relDir);\n\n\t\tif (files.length === 0) {\n\t\t\tprintInfo('No relationship definitions found.');\n\t\t\treturn 0;\n\t\t}\n\n\t\tconst rows = files\n\t\t\t.map(summarizeRelationshipFile)\n\t\t\t.filter((r): r is RelationshipSummaryRow => r !== null);\n\n\t\tif (isJsonMode()) {\n\t\t\tprintJson({\n\t\t\t\tcommand: 'relationship list',\n\t\t\t\trelationships: rows,\n\t\t\t});\n\t\t\treturn 0;\n\t\t}\n\n\t\tconst nameW = Math.max(4, ...rows.map((r) => r.name.length));\n\t\tconst fromW = Math.max(4, ...rows.map((r) => r.from.length));\n\t\tconst toW = Math.max(2, ...rows.map((r) => r.to.length));\n\n\t\tconsole.log(\n\t\t\ttheme.muted(\n\t\t\t\t`${padRight('NAME', nameW)} ${padRight('FROM', fromW)} ${padRight('TO', toW)} TYPES FLAGS`\n\t\t\t)\n\t\t);\n\t\tfor (const r of rows) {\n\t\t\tconst flags = [r.temporal ? 'T' : '', r.sourced ? 'S' : ''].filter(Boolean).join(',');\n\t\t\tconsole.log(\n\t\t\t\t`${padRight(r.name, nameW)} ${padRight(r.from, fromW)} ${padRight(r.to, toW)} ${padRight(String(r.types), 5)} ${flags}`\n\t\t\t);\n\t\t}\n\t\treturn 0;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// NounModule default export\n// ---------------------------------------------------------------------------\n\nconst relationshipNoun: NounModule = {\n\tname: 'relationship',\n\tcommandClasses: [RelationshipNewCommand, RelationshipListCommand] as CommandClass[],\n\tsummary,\n\thints,\n};\n\nexport default relationshipNoun;\n","/**\n * `codegen init` shortcut — aliases `codegen project init`.\n *\n * Kept as a thin subclass so help output still shows the canonical form\n * while users can type the shorter name.\n */\n\nimport { ProjectInitCommand } from '../commands/project.js';\n\nexport class InitShortcut extends ProjectInitCommand {\n\tstatic paths = [['init']];\n\tstatic usage = ProjectInitCommand.usage;\n}\n\nexport default InitShortcut;\n","#!/usr/bin/env node\n/**\n * codegen — root CLI entry point.\n *\n * Registers every noun module with a single Clipanion Cli instance. Each\n * noun contributes its Command classes plus an auto-generated zero-verb\n * summary command (see {@link noun-module.ts}).\n *\n * The transition plan: this binary runs alongside the legacy `src/cli.ts`\n * until all nouns are migrated. `package.json` `bin.codegen` only flips to\n * this file once enough nouns are in place.\n */\n\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { Builtins, Cli, Command } from 'clipanion';\nimport { buildNounSummaryCommand, type NounModule } from './noun-module.js';\nimport { setJsonMode } from './ui/json.js';\nimport { loadContext } from './shared/context.js';\nimport { renderPane } from './ui/pane.js';\nimport { renderHints } from './ui/hints.js';\nimport { theme } from './ui/theme.js';\nimport { icons } from './ui/icons.js';\n\n// ---------------------------------------------------------------------------\n// Package metadata\n// ---------------------------------------------------------------------------\n\nfunction readVersion(): string {\n\ttry {\n\t\tconst pkgPath = join(import.meta.dirname, '..', '..', 'package.json');\n\t\tconst pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n\t\treturn typeof pkg.version === 'string' ? pkg.version : '0.0.0';\n\t} catch {\n\t\treturn '0.0.0';\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Root summary command: `codegen` with no args\n// ---------------------------------------------------------------------------\n\nclass RootSummaryCommand extends Command {\n\tstatic paths = [Command.Default];\n\tstatic usage = Command.Usage({\n\t\tdescription: 'Show project status and available noun commands',\n\t});\n\n\tasync execute(): Promise<number> {\n\t\tconst ctx = await loadContext();\n\n\t\tif (!ctx.isInitialized) {\n\t\t\trenderPane({\n\t\t\t\ttitle: 'codegen',\n\t\t\t\tbody: [\n\t\t\t\t\t'No codegen.config.yaml and no entities/ directory detected.',\n\t\t\t\t\t'',\n\t\t\t\t\t` ${theme.muted('Run')} ${theme.system('codegen init')} ${theme.muted(\n\t\t\t\t\t\t'to scaffold a project'\n\t\t\t\t\t)}`,\n\t\t\t\t\t` ${theme.muted('Or')} ${theme.system('codegen entity')} ${theme.muted(\n\t\t\t\t\t\t'to see entity-level hints'\n\t\t\t\t\t)}`,\n\t\t\t\t],\n\t\t\t});\n\t\t\treturn 0;\n\t\t}\n\n\t\trenderPane({\n\t\t\ttitle: 'codegen',\n\t\t\tbody: [\n\t\t\t\t`${theme.success(icons.check)} project initialized`,\n\t\t\t\t` config: ${ctx.configPath ?? '(none)'}`,\n\t\t\t\t` entities: ${ctx.entityCount}`,\n\t\t\t\t` subsystems: ${ctx.installedSubsystems.length}/4 installed`,\n\t\t\t],\n\t\t});\n\t\trenderHints([\n\t\t\t{ command: 'codegen entity', description: 'Entity summary + hints' },\n\t\t\t{ command: 'codegen subsystem', description: 'Subsystem summary + hints' },\n\t\t\t{ command: 'codegen dev', description: 'Dev environment status + controls' },\n\t\t]);\n\t\treturn 0;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Registry — populated by each phase as nouns are implemented.\n// ---------------------------------------------------------------------------\n\nconst nouns: NounModule[] = [];\n\n// Phase 2 will push entityNoun here; Phase 3 will push subsystemNoun.\n// Dynamic imports avoid pulling in noun code until it exists.\nasync function loadNouns(): Promise<void> {\n\ttry {\n\t\tconst mod = await import('./commands/entity.js');\n\t\tif (mod?.default) nouns.push(mod.default as NounModule);\n\t} catch {\n\t\t// entity noun not implemented yet\n\t}\n\ttry {\n\t\tconst mod = await import('./commands/subsystem.js');\n\t\tif (mod?.default) nouns.push(mod.default as NounModule);\n\t} catch {\n\t\t// subsystem noun not implemented yet\n\t}\n\ttry {\n\t\tconst mod = await import('./commands/project.js');\n\t\tif (mod?.default) nouns.push(mod.default as NounModule);\n\t} catch {\n\t\t// project noun not implemented yet\n\t}\n\ttry {\n\t\tconst mod = await import('./commands/dev.js');\n\t\tif (mod?.default) nouns.push(mod.default as NounModule);\n\t} catch {\n\t\t// dev noun not implemented yet\n\t}\n\ttry {\n\t\tconst mod = await import('./commands/relationship.js');\n\t\tif (mod?.default) nouns.push(mod.default as NounModule);\n\t} catch {\n\t\t// relationship noun not implemented yet\n\t}\n}\n\nasync function loadShortcuts(cli: Cli): Promise<void> {\n\ttry {\n\t\tconst mod = await import('./shortcuts/init.js');\n\t\tif (mod?.default) cli.register(mod.default);\n\t} catch {\n\t\t// shortcut not implemented\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Bootstrap\n// ---------------------------------------------------------------------------\n\nasync function main(): Promise<void> {\n\t// Detect --json early so UI helpers short-circuit from the first call.\n\tconst argv = process.argv.slice(2);\n\tif (argv.includes('--json')) setJsonMode(true);\n\n\tawait loadNouns();\n\n\tconst cli = new Cli({\n\t\tbinaryLabel: 'codegen',\n\t\tbinaryName: 'codegen',\n\t\tbinaryVersion: readVersion(),\n\t});\n\n\tcli.register(Builtins.HelpCommand);\n\tcli.register(Builtins.VersionCommand);\n\tcli.register(RootSummaryCommand);\n\n\tawait loadShortcuts(cli);\n\n\tfor (const noun of nouns) {\n\t\tfor (const CommandClass of noun.commandClasses) {\n\t\t\tcli.register(CommandClass);\n\t\t}\n\t\tcli.register(buildNounSummaryCommand(noun));\n\t}\n\n\tawait cli.runExit(argv);\n}\n\nmain().catch((err: unknown) => {\n\tconst msg = err instanceof Error ? err.message : String(err);\n\tconsole.error(`${theme.error(icons.error)} ${msg}`);\n\tprocess.exit(1);\n});\n","/**\n * NounModule abstraction — see ADR-015 and SPEC-CLI-01.\n *\n * Each CLI noun (entity, subsystem, project, manifest) exports a NounModule.\n * The root CLI registers each noun's command classes and builds a zero-verb\n * summary command on the fly via {@link buildNounSummaryCommand}.\n */\n\nimport { Command, Option } from 'clipanion';\nimport type { CommandClass } from 'clipanion';\nimport type { Context } from './shared/context.js';\nimport { loadContext } from './shared/context.js';\nimport { renderPane, type PaneOutput } from './ui/pane.js';\nimport { renderHints, type Hint } from './ui/hints.js';\nimport { isJsonMode, printJson, setJsonMode } from './ui/json.js';\n\nexport type { PaneOutput } from './ui/pane.js';\nexport type { Hint } from './ui/hints.js';\n\nexport interface NounModule {\n\tname: string;\n\tcommandClasses: Array<CommandClass>;\n\tsummary(ctx: Context): Promise<PaneOutput>;\n\thints(ctx: Context): Promise<Hint[]>;\n}\n\n/**\n * Build a Clipanion Command class whose path is `[[noun.name]]`. Loads the\n * shared Context, renders the noun's summary + hints (or emits JSON).\n */\nexport function buildNounSummaryCommand(noun: NounModule): CommandClass {\n\tclass NounSummaryCommand extends Command {\n\t\tstatic paths = [[noun.name]];\n\t\tstatic usage = Command.Usage({\n\t\t\tdescription: `Show ${noun.name} summary and suggested next commands`,\n\t\t});\n\n\t\tjson = Option.Boolean('--json', false);\n\t\tcwd = Option.String('--cwd', { required: false });\n\t\tconfigPath = Option.String('--config', { required: false });\n\t\tverbose = Option.Boolean('--verbose,-v', false);\n\n\t\tasync execute(): Promise<number> {\n\t\t\tif (this.json) setJsonMode(true);\n\t\t\tconst ctx = await loadContext({\n\t\t\t\tcwd: this.cwd,\n\t\t\t\tconfigPath: this.configPath,\n\t\t\t\tjson: this.json,\n\t\t\t\tverbose: this.verbose,\n\t\t\t});\n\t\t\tconst [pane, hints] = await Promise.all([noun.summary(ctx), noun.hints(ctx)]);\n\n\t\t\tif (isJsonMode()) {\n\t\t\t\tprintJson({ noun: noun.name, summary: pane, hints });\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\trenderPane(pane);\n\t\t\trenderHints(hints);\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t// Preserve a descriptive class name for debugging + Clipanion introspection.\n\tObject.defineProperty(NounSummaryCommand, 'name', {\n\t\tvalue: `${noun.name[0].toUpperCase()}${noun.name.slice(1)}SummaryCommand`,\n\t});\n\treturn NounSummaryCommand as CommandClass;\n}\n"],"mappings":"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","names":["existsSync","readdirSync","readFileSync","join","readdirSync","join","existsSync","readdirSync","readFileSync","join","getAllTsFiles","existsSync","join","existsSync","statSync","join","hints","z","readFileSync","existsSync","path","readdirSync","join","path","path","readFileSync","existsSync","readdirSync","statSync","join","init_types","init_types","init_types","join","execSync","path","fs","path","fs","path","Command","Option","listEntityYamls","fs","path","runtimeRoot","fs","path","fs","path","Command","Option","summary","hints","fs","path","fs","path","Command","Option","stringifyYaml","summary","hints","resolve","fs","path","execSync","Command","Option","summary","hints","fs","path","Command","Option","padRight","summary","hints","readFileSync","join","Command","hints","join","readFileSync","Command"]}