@specverse/engines 4.1.30 → 4.2.1

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 (285) hide show
  1. package/assets/examples/manifests/frontend-only.yaml +3 -6
  2. package/assets/examples/manifests/fullstack-app.yaml +5 -7
  3. package/assets/examples/manifests/fullstack-monorepo.yaml +3 -6
  4. package/assets/templates/default/specs/main.specly +65 -0
  5. package/dist/inference/comprehensive-engine.d.ts.map +1 -1
  6. package/dist/inference/comprehensive-engine.js +3 -19
  7. package/dist/inference/comprehensive-engine.js.map +1 -1
  8. package/dist/inference/core/rule-engine.d.ts +31 -0
  9. package/dist/inference/core/rule-engine.d.ts.map +1 -1
  10. package/dist/inference/core/rule-engine.js +117 -33
  11. package/dist/inference/core/rule-engine.js.map +1 -1
  12. package/dist/inference/core/rule-file-types.d.ts +0 -2
  13. package/dist/inference/core/rule-file-types.d.ts.map +1 -1
  14. package/dist/inference/core/rule-file-types.js +3 -6
  15. package/dist/inference/core/rule-file-types.js.map +1 -1
  16. package/dist/inference/core/rule-loader.d.ts +5 -15
  17. package/dist/inference/core/rule-loader.d.ts.map +1 -1
  18. package/dist/inference/core/rule-loader.js +43 -132
  19. package/dist/inference/core/rule-loader.js.map +1 -1
  20. package/dist/inference/core/types.d.ts +0 -6
  21. package/dist/inference/core/types.d.ts.map +1 -1
  22. package/dist/inference/core/types.js +0 -4
  23. package/dist/inference/core/types.js.map +1 -1
  24. package/dist/inference/logical/generators/component-type-resolver.d.ts +0 -26
  25. package/dist/inference/logical/generators/component-type-resolver.d.ts.map +1 -1
  26. package/dist/inference/logical/generators/component-type-resolver.js +0 -19
  27. package/dist/inference/logical/generators/component-type-resolver.js.map +1 -1
  28. package/dist/inference/logical/generators/specialist-view-expander.d.ts +1 -17
  29. package/dist/inference/logical/generators/specialist-view-expander.d.ts.map +1 -1
  30. package/dist/inference/logical/generators/specialist-view-expander.js +0 -15
  31. package/dist/inference/logical/generators/specialist-view-expander.js.map +1 -1
  32. package/dist/inference/logical/generators/view-generator.d.ts +4 -14
  33. package/dist/inference/logical/generators/view-generator.d.ts.map +1 -1
  34. package/dist/inference/logical/generators/view-generator.js +6 -26
  35. package/dist/inference/logical/generators/view-generator.js.map +1 -1
  36. package/dist/inference/logical/index.d.ts +2 -2
  37. package/dist/inference/logical/index.d.ts.map +1 -1
  38. package/dist/inference/logical/logical-engine.d.ts.map +1 -1
  39. package/dist/inference/logical/logical-engine.js +17 -80
  40. package/dist/inference/logical/logical-engine.js.map +1 -1
  41. package/dist/inference/quint-transpiler.d.ts +5 -3
  42. package/dist/inference/quint-transpiler.d.ts.map +1 -1
  43. package/dist/inference/quint-transpiler.js +11 -6
  44. package/dist/inference/quint-transpiler.js.map +1 -1
  45. package/dist/libs/instance-factories/CURVED-INTERFACE.md +278 -0
  46. package/dist/libs/instance-factories/README.md +73 -0
  47. package/dist/libs/instance-factories/applications/README.md +51 -0
  48. package/dist/libs/instance-factories/applications/generic-app.yaml +52 -0
  49. package/{libs/instance-factories/applications/react-app.yaml → dist/libs/instance-factories/applications/react-app-runtime.yaml} +30 -77
  50. package/dist/libs/instance-factories/applications/react-app-starter.yaml +143 -0
  51. package/dist/libs/instance-factories/applications/templates/react/env-example-generator.js +24 -2
  52. package/dist/libs/instance-factories/applications/templates/react/vite-config-generator.js +54 -33
  53. package/dist/libs/instance-factories/applications/templates/react-starter/README.md +211 -0
  54. package/dist/libs/instance-factories/applications/templates/react-starter/api-types-starter-generator.js +69 -0
  55. package/dist/libs/instance-factories/applications/templates/react-starter/app-tsx-generator.js +110 -0
  56. package/dist/libs/instance-factories/applications/templates/react-starter/belongs-to.js +40 -0
  57. package/dist/libs/instance-factories/applications/templates/react-starter/dashboard-body-composer.js +129 -0
  58. package/dist/libs/instance-factories/applications/templates/react-starter/detail-body-composer.js +80 -0
  59. package/dist/libs/instance-factories/applications/templates/react-starter/form-body-composer.js +217 -0
  60. package/dist/libs/instance-factories/applications/templates/react-starter/helpers-emitter.js +51 -0
  61. package/dist/libs/instance-factories/applications/templates/react-starter/html-to-jsx.js +192 -0
  62. package/dist/libs/instance-factories/applications/templates/react-starter/list-body-composer.js +56 -0
  63. package/dist/libs/instance-factories/applications/templates/react-starter/orchestrator.js +41 -0
  64. package/dist/libs/instance-factories/applications/templates/react-starter/package-json-generator.js +38 -0
  65. package/dist/libs/instance-factories/applications/templates/react-starter/regen-safety.js +89 -0
  66. package/dist/libs/instance-factories/applications/templates/react-starter/skeletons/dashboard.tsx.template +49 -0
  67. package/dist/libs/instance-factories/applications/templates/react-starter/skeletons/detail.tsx.template +96 -0
  68. package/dist/libs/instance-factories/applications/templates/react-starter/skeletons/form.tsx.template +116 -0
  69. package/dist/libs/instance-factories/applications/templates/react-starter/skeletons/list.tsx.template +74 -0
  70. package/dist/libs/instance-factories/applications/templates/react-starter/use-api-hooks-starter-generator.js +95 -0
  71. package/dist/libs/instance-factories/applications/templates/react-starter/view-emitter.js +81 -0
  72. package/dist/libs/instance-factories/applications/templates/react-starter/views-generator.js +66 -0
  73. package/dist/libs/instance-factories/archived/fastify-prisma.yaml +104 -0
  74. package/dist/libs/instance-factories/cli/README.md +43 -0
  75. package/dist/libs/instance-factories/cli/commander-js.yaml +55 -0
  76. package/dist/libs/instance-factories/cli/templates/commander/command-generator.js +63 -12
  77. package/dist/libs/instance-factories/communication/README.md +47 -0
  78. package/dist/libs/instance-factories/communication/event-emitter.yaml +60 -0
  79. package/dist/libs/instance-factories/communication/rabbitmq-events.yaml +87 -0
  80. package/dist/libs/instance-factories/controllers/README.md +42 -0
  81. package/dist/libs/instance-factories/controllers/fastify.yaml +139 -0
  82. package/dist/libs/instance-factories/controllers/templates/fastify/server-generator.js +29 -2
  83. package/dist/libs/instance-factories/infrastructure/README.md +29 -0
  84. package/dist/libs/instance-factories/infrastructure/docker-k8s.yaml +61 -0
  85. package/dist/libs/instance-factories/orms/README.md +54 -0
  86. package/dist/libs/instance-factories/orms/prisma.yaml +89 -0
  87. package/dist/libs/instance-factories/orms/templates/prisma/schema-generator.js +2 -2
  88. package/dist/libs/instance-factories/scaffolding/README.md +49 -0
  89. package/dist/libs/instance-factories/scaffolding/generic-scaffold.yaml +65 -0
  90. package/dist/libs/instance-factories/sdks/README.md +28 -0
  91. package/dist/libs/instance-factories/sdks/python-sdk.yaml +66 -0
  92. package/dist/libs/instance-factories/sdks/typescript-sdk.yaml +59 -0
  93. package/dist/libs/instance-factories/services/README.md +55 -0
  94. package/dist/libs/instance-factories/services/prisma-services.yaml +71 -0
  95. package/dist/libs/instance-factories/storage/README.md +34 -0
  96. package/dist/libs/instance-factories/storage/mongodb.yaml +79 -0
  97. package/dist/libs/instance-factories/storage/postgresql.yaml +75 -0
  98. package/dist/libs/instance-factories/storage/redis.yaml +79 -0
  99. package/dist/libs/instance-factories/testing/README.md +40 -0
  100. package/dist/libs/instance-factories/testing/vitest-tests.yaml +63 -0
  101. package/dist/libs/instance-factories/tools/README.md +70 -0
  102. package/dist/libs/instance-factories/tools/mcp.yaml +36 -0
  103. package/dist/libs/instance-factories/tools/vscode.yaml +35 -0
  104. package/dist/libs/instance-factories/validation/README.md +38 -0
  105. package/dist/libs/instance-factories/validation/zod.yaml +56 -0
  106. package/dist/realize/engines/code-generator.d.ts.map +1 -1
  107. package/dist/realize/engines/code-generator.js +3 -0
  108. package/dist/realize/engines/code-generator.js.map +1 -1
  109. package/dist/realize/index.d.ts.map +1 -1
  110. package/dist/realize/index.js +15 -22
  111. package/dist/realize/index.js.map +1 -1
  112. package/dist/registry/utils/manifest-adapter.d.ts +8 -1
  113. package/dist/registry/utils/manifest-adapter.d.ts.map +1 -1
  114. package/dist/registry/utils/manifest-adapter.js +8 -1
  115. package/dist/registry/utils/manifest-adapter.js.map +1 -1
  116. package/libs/instance-factories/applications/react-app-starter.yaml +143 -0
  117. package/libs/instance-factories/applications/templates/react/env-example-generator.ts +24 -2
  118. package/libs/instance-factories/applications/templates/react/vite-config-generator.ts +54 -33
  119. package/libs/instance-factories/applications/templates/react-starter/README.md +211 -0
  120. package/libs/instance-factories/applications/templates/react-starter/__tests__/dashboard-body-composer.test.ts +153 -0
  121. package/libs/instance-factories/applications/templates/react-starter/__tests__/detail-body-composer.test.ts +146 -0
  122. package/libs/instance-factories/applications/templates/react-starter/__tests__/form-body-composer.test.ts +188 -0
  123. package/libs/instance-factories/applications/templates/react-starter/__tests__/helpers-emitter.test.ts +55 -0
  124. package/libs/instance-factories/applications/templates/react-starter/__tests__/html-to-jsx.test.ts +140 -0
  125. package/libs/instance-factories/applications/templates/react-starter/__tests__/list-body-composer.test.ts +146 -0
  126. package/libs/instance-factories/applications/templates/react-starter/__tests__/orchestrator.test.ts +184 -0
  127. package/libs/instance-factories/applications/templates/react-starter/__tests__/parity-p2-factory-imports.test.ts +116 -0
  128. package/libs/instance-factories/applications/templates/react-starter/__tests__/parity-p3-rendered-output.test.ts +183 -0
  129. package/libs/instance-factories/applications/templates/react-starter/__tests__/regen-safety.test.ts +144 -0
  130. package/libs/instance-factories/applications/templates/react-starter/__tests__/starter-generators.test.ts +114 -0
  131. package/libs/instance-factories/applications/templates/react-starter/__tests__/view-emitter.test.ts +107 -0
  132. package/libs/instance-factories/applications/templates/react-starter/__tests__/views-generator.test.ts +139 -0
  133. package/libs/instance-factories/applications/templates/react-starter/api-types-starter-generator.ts +98 -0
  134. package/libs/instance-factories/applications/templates/react-starter/app-tsx-generator.ts +141 -0
  135. package/libs/instance-factories/applications/templates/react-starter/belongs-to.ts +82 -0
  136. package/libs/instance-factories/applications/templates/react-starter/dashboard-body-composer.ts +189 -0
  137. package/libs/instance-factories/applications/templates/react-starter/detail-body-composer.ts +135 -0
  138. package/libs/instance-factories/applications/templates/react-starter/form-body-composer.ts +383 -0
  139. package/libs/instance-factories/applications/templates/react-starter/helpers-emitter.ts +66 -0
  140. package/libs/instance-factories/applications/templates/react-starter/html-to-jsx.ts +334 -0
  141. package/libs/instance-factories/applications/templates/react-starter/list-body-composer.ts +146 -0
  142. package/libs/instance-factories/applications/templates/react-starter/orchestrator.ts +95 -0
  143. package/libs/instance-factories/applications/templates/react-starter/package-json-generator.ts +57 -0
  144. package/libs/instance-factories/applications/templates/react-starter/regen-safety.ts +157 -0
  145. package/libs/instance-factories/applications/templates/react-starter/skeletons/dashboard.tsx.template +49 -0
  146. package/libs/instance-factories/applications/templates/react-starter/skeletons/detail.tsx.template +96 -0
  147. package/libs/instance-factories/applications/templates/react-starter/skeletons/form.tsx.template +116 -0
  148. package/libs/instance-factories/applications/templates/react-starter/skeletons/list.tsx.template +74 -0
  149. package/libs/instance-factories/applications/templates/react-starter/use-api-hooks-starter-generator.ts +124 -0
  150. package/libs/instance-factories/applications/templates/react-starter/view-emitter.ts +209 -0
  151. package/libs/instance-factories/applications/templates/react-starter/views-generator.ts +137 -0
  152. package/libs/instance-factories/cli/templates/commander/command-generator.ts +63 -12
  153. package/libs/instance-factories/controllers/fastify.yaml +7 -0
  154. package/libs/instance-factories/controllers/templates/fastify/server-generator.ts +36 -2
  155. package/libs/instance-factories/orms/templates/prisma/schema-generator.ts +11 -4
  156. package/package.json +3 -3
  157. package/dist/libs/instance-factories/applications/templates/react/_view-components-source.js +0 -530
  158. package/dist/libs/instance-factories/applications/templates/react/app-tsx-generator.js +0 -73
  159. package/dist/libs/instance-factories/applications/templates/react/field-helpers-generator.js +0 -99
  160. package/dist/libs/instance-factories/applications/templates/react/package-json-generator.js +0 -49
  161. package/dist/libs/instance-factories/applications/templates/react/pattern-adapter-generator.js +0 -156
  162. package/dist/libs/instance-factories/applications/templates/react/react-pattern-adapter.js +0 -935
  163. package/dist/libs/instance-factories/applications/templates/react/relationship-field-generator.js +0 -143
  164. package/dist/libs/instance-factories/applications/templates/react/tailwind-adapter-generator.js +0 -646
  165. package/dist/libs/instance-factories/applications/templates/react/tailwind-adapter-wrapper-generator.js +0 -65
  166. package/dist/libs/instance-factories/applications/templates/react/view-dashboard-generator.js +0 -143
  167. package/dist/libs/instance-factories/applications/templates/react/view-detail-generator.js +0 -143
  168. package/dist/libs/instance-factories/applications/templates/react/view-form-generator.js +0 -355
  169. package/dist/libs/instance-factories/applications/templates/react/view-list-generator.js +0 -91
  170. package/dist/libs/instance-factories/applications/templates/react/view-router-generator.js +0 -79
  171. package/dist/libs/instance-factories/views/index.js +0 -48
  172. package/dist/libs/instance-factories/views/templates/react/adapters/antd-adapter.js +0 -742
  173. package/dist/libs/instance-factories/views/templates/react/adapters/mui-adapter.js +0 -824
  174. package/dist/libs/instance-factories/views/templates/react/adapters/shadcn-adapter.js +0 -719
  175. package/dist/libs/instance-factories/views/templates/react/app-generator.js +0 -45
  176. package/dist/libs/instance-factories/views/templates/react/components-generator.js +0 -820
  177. package/dist/libs/instance-factories/views/templates/react/forms-generator.js +0 -275
  178. package/dist/libs/instance-factories/views/templates/react/frontend-package-json-generator.js +0 -46
  179. package/dist/libs/instance-factories/views/templates/react/hooks-generator.js +0 -81
  180. package/dist/libs/instance-factories/views/templates/react/index-css-generator.js +0 -9
  181. package/dist/libs/instance-factories/views/templates/react/index-html-generator.js +0 -23
  182. package/dist/libs/instance-factories/views/templates/react/main-tsx-generator.js +0 -21
  183. package/dist/libs/instance-factories/views/templates/react/react-component-generator.js +0 -299
  184. package/dist/libs/instance-factories/views/templates/react/router-generator.js +0 -136
  185. package/dist/libs/instance-factories/views/templates/react/router-generic-generator.js +0 -107
  186. package/dist/libs/instance-factories/views/templates/react/shared-utils-generator.js +0 -187
  187. package/dist/libs/instance-factories/views/templates/react/spec-json-generator.js +0 -7
  188. package/dist/libs/instance-factories/views/templates/react/types-generator.js +0 -56
  189. package/dist/libs/instance-factories/views/templates/react/views-metadata-generator.js +0 -27
  190. package/dist/libs/instance-factories/views/templates/react/vite-config-generator.js +0 -29
  191. package/dist/libs/instance-factories/views/templates/runtime/runtime-view-renderer.js +0 -261
  192. package/dist/libs/instance-factories/views/templates/shared/adapter-types.js +0 -34
  193. package/dist/libs/instance-factories/views/templates/shared/atomic-components-registry.js +0 -800
  194. package/dist/libs/instance-factories/views/templates/shared/base-generator.js +0 -305
  195. package/dist/libs/instance-factories/views/templates/shared/component-metadata.js +0 -517
  196. package/dist/libs/instance-factories/views/templates/shared/composite-pattern-types.js +0 -0
  197. package/dist/libs/instance-factories/views/templates/shared/composite-patterns.js +0 -445
  198. package/dist/libs/instance-factories/views/templates/shared/index.js +0 -80
  199. package/dist/libs/instance-factories/views/templates/shared/pattern-validator.js +0 -210
  200. package/dist/libs/instance-factories/views/templates/shared/property-mapper.js +0 -492
  201. package/dist/libs/instance-factories/views/templates/shared/syntax-mapper.js +0 -321
  202. package/dist/realize/index.js.bak +0 -758
  203. package/libs/instance-factories/applications/templates/react/_view-components-source.ts +0 -555
  204. package/libs/instance-factories/applications/templates/react/app-tsx-generator.ts +0 -94
  205. package/libs/instance-factories/applications/templates/react/field-helpers-generator.ts +0 -106
  206. package/libs/instance-factories/applications/templates/react/package-json-generator.ts +0 -57
  207. package/libs/instance-factories/applications/templates/react/pattern-adapter-generator.ts +0 -179
  208. package/libs/instance-factories/applications/templates/react/react-pattern-adapter.tsx +0 -1347
  209. package/libs/instance-factories/applications/templates/react/relationship-field-generator.ts +0 -150
  210. package/libs/instance-factories/applications/templates/react/tailwind-adapter-generator.ts +0 -704
  211. package/libs/instance-factories/applications/templates/react/tailwind-adapter-wrapper-generator.ts +0 -84
  212. package/libs/instance-factories/applications/templates/react/view-dashboard-generator.ts +0 -150
  213. package/libs/instance-factories/applications/templates/react/view-detail-generator.ts +0 -150
  214. package/libs/instance-factories/applications/templates/react/view-form-generator.ts +0 -362
  215. package/libs/instance-factories/applications/templates/react/view-list-generator.ts +0 -98
  216. package/libs/instance-factories/applications/templates/react/view-router-generator.ts +0 -89
  217. package/libs/instance-factories/views/README.md +0 -62
  218. package/libs/instance-factories/views/index.d.ts +0 -13
  219. package/libs/instance-factories/views/index.d.ts.map +0 -1
  220. package/libs/instance-factories/views/index.js +0 -18
  221. package/libs/instance-factories/views/index.js.map +0 -1
  222. package/libs/instance-factories/views/index.ts +0 -45
  223. package/libs/instance-factories/views/react-components.yaml +0 -129
  224. package/libs/instance-factories/views/templates/ARCHITECTURE.md +0 -198
  225. package/libs/instance-factories/views/templates/react/adapters/antd-adapter.ts +0 -869
  226. package/libs/instance-factories/views/templates/react/adapters/mui-adapter.ts +0 -953
  227. package/libs/instance-factories/views/templates/react/adapters/shadcn-adapter.ts +0 -806
  228. package/libs/instance-factories/views/templates/react/app-generator.ts +0 -55
  229. package/libs/instance-factories/views/templates/react/components-generator.ts +0 -938
  230. package/libs/instance-factories/views/templates/react/forms-generator.ts +0 -325
  231. package/libs/instance-factories/views/templates/react/frontend-package-json-generator.ts +0 -57
  232. package/libs/instance-factories/views/templates/react/hooks-generator.ts +0 -106
  233. package/libs/instance-factories/views/templates/react/index-css-generator.ts +0 -14
  234. package/libs/instance-factories/views/templates/react/index-html-generator.ts +0 -34
  235. package/libs/instance-factories/views/templates/react/main-tsx-generator.ts +0 -29
  236. package/libs/instance-factories/views/templates/react/react-component-generator.d.ts +0 -152
  237. package/libs/instance-factories/views/templates/react/react-component-generator.d.ts.map +0 -1
  238. package/libs/instance-factories/views/templates/react/react-component-generator.js +0 -398
  239. package/libs/instance-factories/views/templates/react/react-component-generator.js.map +0 -1
  240. package/libs/instance-factories/views/templates/react/react-component-generator.ts +0 -533
  241. package/libs/instance-factories/views/templates/react/router-generator.ts +0 -197
  242. package/libs/instance-factories/views/templates/react/router-generic-generator.ts +0 -132
  243. package/libs/instance-factories/views/templates/react/shared-utils-generator.ts +0 -196
  244. package/libs/instance-factories/views/templates/react/spec-json-generator.ts +0 -17
  245. package/libs/instance-factories/views/templates/react/types-generator.ts +0 -76
  246. package/libs/instance-factories/views/templates/react/views-metadata-generator.ts +0 -42
  247. package/libs/instance-factories/views/templates/react/vite-config-generator.ts +0 -38
  248. package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.d.ts.map +0 -1
  249. package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.js.map +0 -1
  250. package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.ts +0 -474
  251. package/libs/instance-factories/views/templates/shared/__tests__/composite-patterns.test.ts +0 -242
  252. package/libs/instance-factories/views/templates/shared/adapter-types.d.ts +0 -77
  253. package/libs/instance-factories/views/templates/shared/adapter-types.d.ts.map +0 -1
  254. package/libs/instance-factories/views/templates/shared/adapter-types.js +0 -47
  255. package/libs/instance-factories/views/templates/shared/adapter-types.js.map +0 -1
  256. package/libs/instance-factories/views/templates/shared/adapter-types.ts +0 -142
  257. package/libs/instance-factories/views/templates/shared/atomic-components-registry.d.ts +0 -63
  258. package/libs/instance-factories/views/templates/shared/atomic-components-registry.d.ts.map +0 -1
  259. package/libs/instance-factories/views/templates/shared/atomic-components-registry.js +0 -822
  260. package/libs/instance-factories/views/templates/shared/atomic-components-registry.js.map +0 -1
  261. package/libs/instance-factories/views/templates/shared/atomic-components-registry.ts +0 -908
  262. package/libs/instance-factories/views/templates/shared/base-generator.d.ts +0 -247
  263. package/libs/instance-factories/views/templates/shared/base-generator.d.ts.map +0 -1
  264. package/libs/instance-factories/views/templates/shared/base-generator.js +0 -363
  265. package/libs/instance-factories/views/templates/shared/base-generator.js.map +0 -1
  266. package/libs/instance-factories/views/templates/shared/base-generator.ts +0 -608
  267. package/libs/instance-factories/views/templates/shared/component-metadata.d.ts +0 -254
  268. package/libs/instance-factories/views/templates/shared/component-metadata.d.ts.map +0 -1
  269. package/libs/instance-factories/views/templates/shared/component-metadata.js +0 -602
  270. package/libs/instance-factories/views/templates/shared/component-metadata.js.map +0 -1
  271. package/libs/instance-factories/views/templates/shared/component-metadata.ts +0 -803
  272. package/libs/instance-factories/views/templates/shared/composite-pattern-types.ts +0 -250
  273. package/libs/instance-factories/views/templates/shared/composite-patterns.ts +0 -535
  274. package/libs/instance-factories/views/templates/shared/index.ts +0 -68
  275. package/libs/instance-factories/views/templates/shared/pattern-validator.ts +0 -279
  276. package/libs/instance-factories/views/templates/shared/property-mapper.d.ts +0 -149
  277. package/libs/instance-factories/views/templates/shared/property-mapper.d.ts.map +0 -1
  278. package/libs/instance-factories/views/templates/shared/property-mapper.js +0 -580
  279. package/libs/instance-factories/views/templates/shared/property-mapper.js.map +0 -1
  280. package/libs/instance-factories/views/templates/shared/property-mapper.ts +0 -700
  281. package/libs/instance-factories/views/templates/shared/syntax-mapper.d.ts +0 -143
  282. package/libs/instance-factories/views/templates/shared/syntax-mapper.d.ts.map +0 -1
  283. package/libs/instance-factories/views/templates/shared/syntax-mapper.js +0 -420
  284. package/libs/instance-factories/views/templates/shared/syntax-mapper.js.map +0 -1
  285. package/libs/instance-factories/views/templates/shared/syntax-mapper.ts +0 -539
@@ -0,0 +1,74 @@
1
+ /**
2
+ * {{MODEL_NAME}}ListView — generated by @specverse/realize (ReactAppStarter)
3
+ *
4
+ * Safe to edit. Edits are preserved across regeneration via content
5
+ * hashing (see .specverse-gen/hashes.json). To accept an upstream
6
+ * regeneration of this file, delete it first, then run `spv realize`.
7
+ */
8
+ import { useState, useMemo } from 'react';
9
+ import { use{{PLURAL_MODEL}}Query, useDelete{{MODEL_NAME}}Mutation } from '../hooks/useApi';
10
+ {{RELATED_IMPORTS}}
11
+ import type { {{MODEL_NAME}} } from '../types/api';
12
+
13
+ interface {{MODEL_NAME}}ListViewProps {
14
+ onSelect?: (item: {{MODEL_NAME}}) => void;
15
+ onCreate?: () => void;
16
+ }
17
+
18
+ export function {{MODEL_NAME}}ListView({ onSelect, onCreate }: {{MODEL_NAME}}ListViewProps) {
19
+ const { data: items = [], isLoading, error } = use{{PLURAL_MODEL}}Query();
20
+ const deleteItem = useDelete{{MODEL_NAME}}Mutation();
21
+ {{RELATED_HOOKS}}
22
+ const [searchTerm, setSearchTerm] = useState('');
23
+
24
+ const filtered = useMemo(
25
+ () =>
26
+ items.filter((item: {{MODEL_NAME}}) =>
27
+ // Cast to `any` inside JSX context — `Record<string, unknown>`
28
+ // looks like a JSX opening tag to the TSX parser when this
29
+ // expression ends up inside JSX. `any` is safe here: we only
30
+ // read values for substring-matching against the search term.
31
+ Object.values(item as any).some(v =>
32
+ String(v ?? '').toLowerCase().includes(searchTerm.toLowerCase())
33
+ )
34
+ ),
35
+ [items, searchTerm]
36
+ );
37
+
38
+ if (isLoading) return <div className="p-4 text-gray-500">Loading {{PLURAL_LOWER}}…</div>;
39
+ if (error) return <div className="p-4 text-red-600">Error loading {{PLURAL_LOWER}}: {String(error)}</div>;
40
+
41
+ return (
42
+ <div className="p-6 space-y-4">
43
+ <div className="flex items-center justify-between">
44
+ <input
45
+ type="search"
46
+ placeholder="Search {{PLURAL_LOWER}}…"
47
+ value={searchTerm}
48
+ onChange={e => setSearchTerm(e.target.value)}
49
+ className="w-64 rounded border border-gray-300 px-3 py-2 text-sm"
50
+ />
51
+ <button
52
+ type="button"
53
+ onClick={onCreate}
54
+ className="rounded bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700"
55
+ >
56
+ + New {{MODEL_NAME}}
57
+ </button>
58
+ </div>
59
+
60
+ {/* Pattern-rendered list body (table + rows). Edit freely. */}
61
+ {{BODY}}
62
+
63
+ {filtered.length === 0 && (
64
+ <div className="p-8 text-center text-gray-400">No {{PLURAL_LOWER}} yet.</div>
65
+ )}
66
+
67
+ {deleteItem.isError && (
68
+ <div className="p-2 text-sm text-red-600">
69
+ Delete failed: {String(deleteItem.error)}
70
+ </div>
71
+ )}
72
+ </div>
73
+ );
74
+ }
@@ -0,0 +1,95 @@
1
+ function pluralize(s) {
2
+ if (/y$/.test(s) && !/[aeiou]y$/.test(s)) return s.replace(/y$/, "ies");
3
+ if (/(s|x|z|ch|sh)$/.test(s)) return s + "es";
4
+ return s + "s";
5
+ }
6
+ async function generate(context) {
7
+ const models = Object.keys(context.spec.models ?? {});
8
+ const importsAndTypes = `/**
9
+ * useApi \u2014 typed per-model React Query hooks (ReactAppStarter)
10
+ *
11
+ * Safe to edit. Users who want to reshape their API client or add
12
+ * request/response interceptors should start here. Each hook calls
13
+ * the sibling \`apiClient\` which does the actual fetch; edit
14
+ * \`apiClient.ts\` to change transport concerns (headers, auth, etc.).
15
+ */
16
+
17
+ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
18
+ ${models.map((m) => `import type { ${m} } from '../types/api';`).join("\n")}
19
+
20
+ const API_BASE = import.meta.env.VITE_API_BASE_URL || '';
21
+
22
+ async function fetchJSON<T = unknown>(url: string, init?: RequestInit): Promise<T> {
23
+ const res = await fetch(url, {
24
+ headers: { 'Content-Type': 'application/json' },
25
+ ...init,
26
+ });
27
+ if (!res.ok) {
28
+ throw new Error(\`\${res.status} \${res.statusText} \u2014 \${url}\`);
29
+ }
30
+ if (res.status === 204) return undefined as T;
31
+ return (await res.json()) as T;
32
+ }
33
+ `;
34
+ const hookBlocks = models.map((m) => generateModelHooks(m)).join("\n\n");
35
+ return importsAndTypes + "\n" + hookBlocks + "\n";
36
+ }
37
+ function generateModelHooks(model) {
38
+ const plural = pluralize(model);
39
+ const resource = plural.toLowerCase();
40
+ const modelLower = model.toLowerCase();
41
+ return `// \u2500\u2500\u2500 ${model} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
42
+
43
+ export function use${plural}Query() {
44
+ return useQuery({
45
+ queryKey: ['${resource}'],
46
+ queryFn: () => fetchJSON<${model}[]>(\`\${API_BASE}/api/${resource}\`),
47
+ });
48
+ }
49
+
50
+ export function use${model}Query(id: string | number | undefined) {
51
+ return useQuery({
52
+ queryKey: ['${resource}', id],
53
+ queryFn: () => fetchJSON<${model}>(\`\${API_BASE}/api/${resource}/\${id}\`),
54
+ enabled: id !== undefined && id !== null,
55
+ });
56
+ }
57
+
58
+ export function useCreate${model}Mutation() {
59
+ const qc = useQueryClient();
60
+ return useMutation({
61
+ mutationFn: (data: Partial<${model}>) =>
62
+ fetchJSON<${model}>(\`\${API_BASE}/api/${resource}\`, {
63
+ method: 'POST',
64
+ body: JSON.stringify(data),
65
+ }),
66
+ onSuccess: () => qc.invalidateQueries({ queryKey: ['${resource}'] }),
67
+ });
68
+ }
69
+
70
+ export function useUpdate${model}Mutation() {
71
+ const qc = useQueryClient();
72
+ return useMutation({
73
+ mutationFn: ({ id, data }: { id: string | number; data: Partial<${model}> }) =>
74
+ fetchJSON<${model}>(\`\${API_BASE}/api/${resource}/\${id}\`, {
75
+ method: 'PATCH',
76
+ body: JSON.stringify(data),
77
+ }),
78
+ onSuccess: () => qc.invalidateQueries({ queryKey: ['${resource}'] }),
79
+ });
80
+ }
81
+
82
+ export function useDelete${model}Mutation() {
83
+ const qc = useQueryClient();
84
+ return useMutation({
85
+ mutationFn: (id: string | number) =>
86
+ fetchJSON<void>(\`\${API_BASE}/api/${resource}/\${id}\`, { method: 'DELETE' }),
87
+ onSuccess: () => qc.invalidateQueries({ queryKey: ['${resource}'] }),
88
+ });
89
+ }`;
90
+ }
91
+ var stdin_default = generate;
92
+ export {
93
+ stdin_default as default,
94
+ generate
95
+ };
@@ -0,0 +1,81 @@
1
+ import { readFileSync } from "fs";
2
+ import { join, dirname } from "path";
3
+ import { fileURLToPath } from "url";
4
+ import { extractBelongsToTargets, pluralize as pluralizeShared } from "./belongs-to.js";
5
+ function emitView(context) {
6
+ const skeleton = loadSkeleton(context.view.type);
7
+ const bodyJsx = context.renderBody(context);
8
+ const substitutions = buildSubstitutions(context, bodyJsx);
9
+ return applySubstitutions(skeleton, substitutions);
10
+ }
11
+ const SKELETON_BY_VIEW_TYPE = {
12
+ list: "list.tsx.template",
13
+ detail: "detail.tsx.template",
14
+ form: "form.tsx.template",
15
+ dashboard: "dashboard.tsx.template"
16
+ // Specialist types (board, timeline, calendar, analytics, workflow,
17
+ // wizard, comparison, settings, map, feed, profile) come online in
18
+ // Phase 2e.
19
+ };
20
+ function loadSkeleton(viewType) {
21
+ const filename = SKELETON_BY_VIEW_TYPE[viewType.toLowerCase()];
22
+ if (!filename) {
23
+ throw new Error(
24
+ `No skeleton registered for view type "${viewType}". Known types: ${Object.keys(SKELETON_BY_VIEW_TYPE).join(", ")}.`
25
+ );
26
+ }
27
+ const here = dirname(fileURLToPath(import.meta.url));
28
+ const path = join(here, "skeletons", filename);
29
+ return readFileSync(path, "utf8");
30
+ }
31
+ function buildSubstitutions(context, body) {
32
+ const modelName = context.model.name;
33
+ const pluralModel = pluralize(modelName);
34
+ const { imports, hooks } = buildBelongsToWiring(context);
35
+ return {
36
+ MODEL_NAME: modelName,
37
+ PLURAL_MODEL: pluralModel,
38
+ PLURAL_LOWER: pluralModel.toLowerCase(),
39
+ SINGULAR_LOWER: modelName.toLowerCase(),
40
+ BODY: body,
41
+ RELATED_IMPORTS: imports,
42
+ RELATED_HOOKS: hooks
43
+ };
44
+ }
45
+ function buildBelongsToWiring(context) {
46
+ const rels = extractBelongsToTargets(context.model);
47
+ if (rels.length === 0) return { imports: "", hooks: "" };
48
+ const hookImportNames = /* @__PURE__ */ new Set();
49
+ for (const rel of rels) {
50
+ hookImportNames.add(`use${pluralizeShared(rel.target)}Query`);
51
+ }
52
+ const helperImport = context.view.type.toLowerCase() === "form" ? "getEntityDisplayName" : "resolveEntityDisplayName";
53
+ const importLines = [];
54
+ importLines.push(
55
+ `import { ${[...hookImportNames].join(", ")} } from '../hooks/useApi';`
56
+ );
57
+ importLines.push(`import { ${helperImport} } from '../lib/entity-display';`);
58
+ const hookLines = rels.map(
59
+ (rel) => ` const { data: ${rel.name}Options = [] } = use${pluralizeShared(rel.target)}Query();`
60
+ );
61
+ return {
62
+ imports: importLines.join("\n"),
63
+ hooks: hookLines.join("\n")
64
+ };
65
+ }
66
+ function applySubstitutions(template, subs) {
67
+ let out = template;
68
+ for (const [key, value] of Object.entries(subs)) {
69
+ const pattern = new RegExp(`\\{\\{${key}\\}\\}`, "g");
70
+ out = out.replace(pattern, value);
71
+ }
72
+ return out;
73
+ }
74
+ function pluralize(s) {
75
+ if (/[^aeiou]y$/i.test(s)) return s.slice(0, -1) + "ies";
76
+ if (/(s|x|z|ch|sh)$/i.test(s)) return s + "es";
77
+ return s + "s";
78
+ }
79
+ export {
80
+ emitView
81
+ };
@@ -0,0 +1,66 @@
1
+ import { emitView } from "./view-emitter.js";
2
+ import { composeListBody } from "./list-body-composer.js";
3
+ import { composeDetailBody } from "./detail-body-composer.js";
4
+ import { composeFormBody } from "./form-body-composer.js";
5
+ import { composeDashboardBody } from "./dashboard-body-composer.js";
6
+ import { emitEntityDisplay } from "./helpers-emitter.js";
7
+ const PRIMARY_VIEW_TYPES = ["list", "detail", "form", "dashboard"];
8
+ const COMPOSER_BY_TYPE = {
9
+ list: composeListBody,
10
+ detail: composeDetailBody,
11
+ form: composeFormBody,
12
+ dashboard: composeDashboardBody
13
+ };
14
+ async function generate(context) {
15
+ const files = {};
16
+ const spec = context.spec;
17
+ const models = spec.models ?? {};
18
+ const viewsBySpec = spec.views ?? {};
19
+ const viewIndex = indexViews(viewsBySpec);
20
+ const skippedSpecialists = [];
21
+ for (const [modelName, model] of Object.entries(models)) {
22
+ for (const viewType of PRIMARY_VIEW_TYPES) {
23
+ const viewName = `${modelName}${capitalize(viewType)}View`;
24
+ const view = viewIndex.get(viewName) ?? synthesizeDefault(modelName, viewType);
25
+ const source = emitView({
26
+ view,
27
+ viewName,
28
+ model,
29
+ modelSchemas: models,
30
+ renderBody: COMPOSER_BY_TYPE[viewType]
31
+ });
32
+ files[`src/views/${viewName}.tsx`] = source;
33
+ }
34
+ }
35
+ for (const [name, view] of Object.entries(viewsBySpec)) {
36
+ if (!PRIMARY_VIEW_TYPES.includes(view.type)) {
37
+ skippedSpecialists.push(`${name} (type=${view.type})`);
38
+ }
39
+ }
40
+ if (skippedSpecialists.length > 0) {
41
+ console.warn(
42
+ `[ReactAppStarter] Skipped ${skippedSpecialists.length} specialist view(s) \u2014 implement composers for: ${[...new Set(Object.values(viewsBySpec).filter((v) => !PRIMARY_VIEW_TYPES.includes(v.type)).map((v) => v.type))].join(", ")}. Skipped: ${skippedSpecialists.join(", ")}`
43
+ );
44
+ }
45
+ files["src/lib/entity-display.ts"] = emitEntityDisplay();
46
+ return files;
47
+ }
48
+ function indexViews(views) {
49
+ const out = /* @__PURE__ */ new Map();
50
+ for (const [name, view] of Object.entries(views)) {
51
+ out.set(name, view);
52
+ }
53
+ return out;
54
+ }
55
+ function synthesizeDefault(modelName, viewType) {
56
+ return {
57
+ type: viewType,
58
+ model: modelName
59
+ };
60
+ }
61
+ function capitalize(s) {
62
+ return s.charAt(0).toUpperCase() + s.slice(1);
63
+ }
64
+ export {
65
+ generate
66
+ };
@@ -0,0 +1,104 @@
1
+ name: FastifyPrismaAPI
2
+ version: "1.0.0"
3
+ category: controller
4
+ description: "Fastify server with Prisma ORM, Zod validation, and JWT authentication"
5
+
6
+ metadata:
7
+ author: "SpecVerse Team"
8
+ license: "MIT"
9
+ tags: [fastify, prisma, typescript, rest-api]
10
+
11
+ compatibility:
12
+ specverse: ">=3.3.0"
13
+ node: ">=18.0.0"
14
+
15
+ capabilities:
16
+ provides:
17
+ - "api.rest"
18
+ - "api.rest.crud"
19
+ - "api.websocket"
20
+ requires: []
21
+
22
+ technology:
23
+ runtime: "node"
24
+ language: "typescript"
25
+ framework: "fastify"
26
+ orm: "prisma"
27
+ validation: "zod"
28
+ authentication: "jwt"
29
+
30
+ dependencies:
31
+ runtime:
32
+ - name: "fastify"
33
+ version: "^4.24.0"
34
+ - name: "@fastify/cors"
35
+ version: "^8.4.0"
36
+ - name: "@fastify/jwt"
37
+ version: "^7.2.0"
38
+ - name: "@fastify/helmet"
39
+ version: "^11.1.0"
40
+ - name: "@fastify/rate-limit"
41
+ version: "^9.0.0"
42
+ - name: "@prisma/client"
43
+ version: "^5.5.0"
44
+ - name: "zod"
45
+ version: "^3.22.0"
46
+
47
+ dev:
48
+ - name: "prisma"
49
+ version: "^5.5.0"
50
+ - name: "@types/node"
51
+ version: "^20.8.0"
52
+ - name: "typescript"
53
+ version: "^5.2.0"
54
+ - name: "tsx"
55
+ version: "^4.0.0"
56
+
57
+ codeTemplates:
58
+ routes:
59
+ engine: typescript
60
+ generator: "libs/instance-factories/backend/templates/fastify/routes-generator.ts"
61
+ outputPattern: "routes/{controller}.ts"
62
+
63
+ services:
64
+ engine: typescript
65
+ generator: "libs/instance-factories/backend/templates/prisma/services-generator.ts"
66
+ outputPattern: "services/{model}.service.ts"
67
+
68
+ schema:
69
+ engine: typescript
70
+ generator: "libs/instance-factories/backend/templates/prisma/schema-generator.ts"
71
+ outputPattern: "prisma/schema.prisma"
72
+
73
+ configuration:
74
+ server:
75
+ port: 3000
76
+ host: "0.0.0.0"
77
+ trustProxy: true
78
+ requestIdLogLabel: "reqId"
79
+ logger:
80
+ level: "info"
81
+ prettyPrint: true
82
+
83
+ orm:
84
+ provider: "postgresql"
85
+ relationMode: "foreignKeys"
86
+ log: ["query", "error", "warn"]
87
+
88
+ middleware:
89
+ cors:
90
+ origin: true
91
+ credentials: true
92
+ helmet:
93
+ enabled: true
94
+ rateLimit:
95
+ max: 100
96
+ timeWindow: "1 minute"
97
+ jwt:
98
+ secret: "${JWT_SECRET}"
99
+ sign:
100
+ expiresIn: "7d"
101
+
102
+ validation:
103
+ stripUnknown: true
104
+ abortEarly: false
@@ -0,0 +1,43 @@
1
+ # CLI Factory
2
+
3
+ Generates Commander.js CLI applications from spec command definitions.
4
+
5
+ ## Definition
6
+
7
+ | File | Description |
8
+ |------|-------------|
9
+ | `commander-js.yaml` | Commander.js v12 CLI with argument parsing, help text, and command routing |
10
+
11
+ ## Generated Output
12
+
13
+ | Generator | Output | Purpose |
14
+ |-----------|--------|---------|
15
+ | `cli-entry-generator` | `backend/src/cli/index.ts` | Main CLI entry point — registers all commands from spec |
16
+ | `command-generator` | `backend/src/cli/commands/{command}.ts` | Individual command files (one per spec command) |
17
+
18
+ The entry generator reads the spec's `commands` section and registers each as a
19
+ Commander.js command with arguments, flags, and help text. Each command file
20
+ delegates to its corresponding service for business logic.
21
+
22
+ ## Technology
23
+
24
+ - **Framework**: Commander.js ^12.0.0
25
+ - **Runtime**: Node.js with tsx for development
26
+ - **Language**: TypeScript
27
+
28
+ ## Capabilities
29
+
30
+ | Provides | Requires |
31
+ |----------|----------|
32
+ | `cli.commands` | `service.controller` |
33
+ | `cli.parser` | |
34
+ | `cli.help` | |
35
+
36
+ ## Spec Integration
37
+
38
+ Commands are defined in the spec with:
39
+ - `arguments` — positional parameters
40
+ - `flags` — optional switches
41
+ - `returns` — output format
42
+ - `exitCodes` — process exit codes
43
+ - `subcommands` — nested command trees
@@ -0,0 +1,55 @@
1
+ name: CommanderJS
2
+ version: "1.0.0"
3
+ category: cli
4
+ description: "Node.js CLI generation using Commander.js"
5
+
6
+ metadata:
7
+ author: "SpecVerse Team"
8
+ license: "MIT"
9
+ tags: [cli, commander, node, typescript]
10
+
11
+ compatibility:
12
+ specverse: ">=3.3.0"
13
+ node: ">=18.0.0"
14
+
15
+ capabilities:
16
+ provides:
17
+ - "cli.commands"
18
+ - "cli.parser"
19
+ - "cli.help"
20
+ requires:
21
+ - "service.controller"
22
+
23
+ technology:
24
+ runtime: "node"
25
+ language: "typescript"
26
+ framework: "commander"
27
+ version: "^12.0.0"
28
+
29
+ dependencies:
30
+ runtime:
31
+ - name: "commander"
32
+ version: "^12.0.0"
33
+
34
+ dev:
35
+ - name: "@types/node"
36
+ version: "^20.8.0"
37
+ - name: "typescript"
38
+ version: "^5.2.0"
39
+ - name: "tsx"
40
+ version: "^4.0.0"
41
+
42
+ codeTemplates:
43
+ cli-entry:
44
+ engine: typescript
45
+ generator: "libs/instance-factories/cli/templates/commander/cli-entry-generator.ts"
46
+ outputPattern: "{backendDir}/src/cli/index.ts"
47
+
48
+ cli-commands:
49
+ engine: typescript
50
+ generator: "libs/instance-factories/cli/templates/commander/command-generator.ts"
51
+ outputPattern: "{backendDir}/src/cli/commands/{command}.ts"
52
+
53
+ configuration:
54
+ outputStructure: "monorepo"
55
+ backendDir: "backend"
@@ -338,22 +338,25 @@ import type { ParserEngine, InferenceEngine, RealizeEngine } from '@specverse/ty
338
338
  process.exit(1);
339
339
  }
340
340
 
341
- // Runtime mode (default): swap ReactApp \u2192 ReactAppRuntime in manifest
341
+ // --static ejects to a standalone starter kit (ReactAppStarter).
342
+ // Default: whatever the manifest declares (ReactAppRuntime in the
343
+ // shipped templates). The swap is a convenience only \u2014 users can
344
+ // achieve the same by editing their manifest directly.
342
345
  let effectiveManifestPath = manifestPath;
343
- if (!options.static) {
346
+ if (options.static) {
344
347
  const manifestContent = readFileSync(manifestPath, 'utf8');
345
- if (/instanceFactory:\\s*["']?ReactApp["']?\\s*$/m.test(manifestContent)) {
348
+ if (/instanceFactory:\\s*["']?ReactAppRuntime["']?\\s*$/m.test(manifestContent)) {
346
349
  const { tmpdir } = await import('os');
347
- const runtimeManifest = manifestContent.replace(
348
- /instanceFactory:\\s*["']?ReactApp["']?\\s*$/gm,
349
- 'instanceFactory: "ReactAppRuntime"'
350
+ const staticManifest = manifestContent.replace(
351
+ /instanceFactory:\\s*["']?ReactAppRuntime["']?\\s*$/gm,
352
+ 'instanceFactory: "ReactAppStarter"'
350
353
  );
351
- effectiveManifestPath = join(tmpdir(), 'specverse-runtime-manifest.yaml');
352
- writeFileSync(effectiveManifestPath, runtimeManifest, 'utf8');
353
- console.log(' Using runtime mode (slim frontend with @specverse/runtime)');
354
+ effectiveManifestPath = join(tmpdir(), 'specverse-static-manifest.yaml');
355
+ writeFileSync(effectiveManifestPath, staticManifest, 'utf8');
356
+ console.log(' Using static mode (standalone starter kit \u2014 ReactAppStarter)');
357
+ } else {
358
+ console.log(' Using static mode (manifest factory unchanged)');
354
359
  }
355
- } else {
356
- console.log(' Using static mode (full frontend generation)');
357
360
  }
358
361
 
359
362
  const realizeEngine = registry.getEngineForCapability('realize') as RealizeEngine;
@@ -502,8 +505,56 @@ import { fileURLToPath } from 'url';`,
502
505
  }
503
506
 
504
507
  copyDir(templateDir, destDir);
508
+
509
+ // If the copied template didn't ship a specs/main.specly, load
510
+ // the canonical default spec from @specverse/engines/assets \u2014
511
+ // same file app-demo's Server Manager "new spec" action uses,
512
+ // so both entry points start a user on the same footing. The
513
+ // template can opt out of this by shipping its own spec.
514
+ const specDestPath = join(destDir, 'specs', 'main.specly');
515
+ if (!existsSync(specDestPath)) {
516
+ try {
517
+ const { createRequire } = await import('module');
518
+ const require = createRequire(import.meta.url);
519
+ const enginesPkg = require.resolve('@specverse/engines/package.json');
520
+ const canonicalSpec = join(
521
+ dirname(enginesPkg),
522
+ 'assets', 'templates', 'default', 'specs', 'main.specly'
523
+ );
524
+ if (existsSync(canonicalSpec)) {
525
+ let content = readFileSync(canonicalSpec, 'utf8');
526
+ for (const [key, val] of Object.entries(vars)) {
527
+ content = content.split(key).join(val);
528
+ }
529
+ mkdirSync(join(destDir, 'specs'), { recursive: true });
530
+ writeFileSync(specDestPath, content);
531
+ }
532
+ } catch { /* engines not installed or template missing \u2014 proceed */ }
533
+ }
534
+
535
+ // --static: flip any ReactAppRuntime mappings in the copied
536
+ // manifests to ReactAppStarter so the user gets standalone-starter
537
+ // output on first \`spv realize\` without having to re-pass the
538
+ // flag. Same semantic as \`spv realize --static\` \u2014 just applied
539
+ // at init time. Idempotent; no-op for templates without a frontend.
540
+ if (options.static) {
541
+ const manifestsDir = join(destDir, 'manifests');
542
+ if (existsSync(manifestsDir)) {
543
+ for (const f of readdirSync(manifestsDir)) {
544
+ if (!f.endsWith('.yaml') && !f.endsWith('.yml')) continue;
545
+ const p = join(manifestsDir, f);
546
+ const before = readFileSync(p, 'utf8');
547
+ const after = before.replace(
548
+ /instanceFactory:\\s*["']?ReactAppRuntime["']?/g,
549
+ 'instanceFactory: "ReactAppStarter"'
550
+ );
551
+ if (after !== before) writeFileSync(p, after, 'utf8');
552
+ }
553
+ }
554
+ }
555
+
505
556
  console.log('Project created: ' + destDir);
506
- console.log('Template: ' + templateName);
557
+ console.log('Template: ' + templateName + (options.static ? ' (static / ReactAppStarter)' : ''));
507
558
  console.log('');
508
559
 
509
560
  // Build the "Next steps" hint from the actual scripts the
@@ -0,0 +1,47 @@
1
+ # Communication Factory
2
+
3
+ Event-driven messaging infrastructure with publisher/subscriber generation.
4
+
5
+ ## Definitions
6
+
7
+ | File | Description |
8
+ |------|-------------|
9
+ | `event-emitter.yaml` | In-memory event bus using EventEmitter3 (development/testing) |
10
+ | `rabbitmq-events.yaml` | RabbitMQ AMQP bus for production pub/sub messaging |
11
+
12
+ ## Generated Output
13
+
14
+ ### EventEmitter (`eventemitter/`)
15
+
16
+ | Generator | Output | Purpose |
17
+ |-----------|--------|---------|
18
+ | `bus-generator` | `src/events/eventBus.ts` | Singleton event bus with typed event names |
19
+ | `publisher-generator` | `src/events/publishers/{event}Publisher.ts` | Per-event publisher (one per spec event) |
20
+ | `subscriber-generator` | `src/events/subscribers/{event}Subscriber.ts` | Per-event subscriber with handler logic |
21
+
22
+ ### RabbitMQ (`rabbitmq/` — defined, templates pending)
23
+
24
+ | Generator | Output | Purpose |
25
+ |-----------|--------|---------|
26
+ | `publisher-generator` | `src/events/publishers/{event}Publisher.ts` | AMQP publisher with confirms |
27
+ | `subscriber-generator` | `src/events/subscribers/{event}Subscriber.ts` | AMQP consumer with ack/nack |
28
+ | `connection-generator` | `src/events/connection.ts` | RabbitMQ connection management |
29
+
30
+ ## Technology
31
+
32
+ - **EventEmitter**: eventemitter3 ^5.0.0 (zero-dependency, in-process)
33
+ - **RabbitMQ**: amqplib ^0.10.3 (topic exchange, durable queues, prefetch)
34
+
35
+ ## Capabilities
36
+
37
+ | Provides | Requires |
38
+ |----------|----------|
39
+ | `messaging.pubsub` | (none) |
40
+ | `messaging.events` | |
41
+ | `messaging.inmemory` (EventEmitter) | |
42
+ | `messaging.queue` (RabbitMQ) | |
43
+
44
+ ## Configuration
45
+
46
+ EventEmitter: `maxListeners: 100`, `captureRejections: true`
47
+ RabbitMQ: topic exchange, durable queues, prefetch 10, persistent messages, confirm-select