@specverse/engine-realize 3.5.3

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 (420) hide show
  1. package/assets/examples/09-api/ai-spec.yaml +194 -0
  2. package/assets/examples/09-api/converted.yaml +95 -0
  3. package/assets/examples/09-api/diagram-architecture.mmd +10 -0
  4. package/assets/examples/09-api/diagram-er.mmd +10 -0
  5. package/assets/examples/09-api/documentation.html +104 -0
  6. package/assets/examples/09-api/documentation.md +95 -0
  7. package/assets/examples/09-api/inferred-spec.yaml +420 -0
  8. package/assets/examples/09-api/openapi.json +61 -0
  9. package/assets/examples/10-api/README.md +216 -0
  10. package/assets/examples/10-api/ai-spec.yaml +194 -0
  11. package/assets/examples/10-api/converted.yaml +96 -0
  12. package/assets/examples/10-api/diagram-architecture.mmd +10 -0
  13. package/assets/examples/10-api/diagram-er.mmd +10 -0
  14. package/assets/examples/10-api/documentation.html +104 -0
  15. package/assets/examples/10-api/documentation.md +95 -0
  16. package/assets/examples/10-api/inferred-spec.yaml +7 -0
  17. package/assets/examples/10-api/metadata.yaml +89 -0
  18. package/assets/examples/10-api/openapi.json +61 -0
  19. package/assets/examples/10-api/package-integration-test.js +177 -0
  20. package/assets/examples/10-api/usage-example.js +323 -0
  21. package/assets/examples/10-api/usage-example.ts +363 -0
  22. package/assets/examples/10-api/workflow-test.js +113 -0
  23. package/assets/examples/manifests/01-simple-default-mappings.yaml +36 -0
  24. package/assets/examples/manifests/02-capability-mappings.yaml +55 -0
  25. package/assets/examples/manifests/03-hybrid-mappings.yaml +109 -0
  26. package/assets/examples/manifests/README.md +245 -0
  27. package/assets/examples/manifests/backend-only.yaml +43 -0
  28. package/assets/examples/manifests/blog-api.md +78 -0
  29. package/assets/examples/manifests/blog-api.specly +79 -0
  30. package/assets/examples/manifests/frontend-only.yaml +27 -0
  31. package/assets/examples/manifests/fullstack-app.yaml +44 -0
  32. package/assets/examples/manifests/fullstack-monorepo.yaml +62 -0
  33. package/assets/examples/validate-examples-with-expected-failures.cjs +328 -0
  34. package/assets/examples/validate-examples.cjs +225 -0
  35. package/assets/examples-decomposed/cloud-native-manifest.example.yaml +8 -0
  36. package/assets/examples-decomposed/cloud-native-manifest.md +379 -0
  37. package/assets/examples-decomposed/cloud-native-manifest.specly +60 -0
  38. package/assets/examples-decomposed/docker-compose-manifest.example.yaml +8 -0
  39. package/assets/examples-decomposed/docker-compose-manifest.md +326 -0
  40. package/assets/examples-decomposed/docker-compose-manifest.specly +40 -0
  41. package/assets/examples-decomposed/kubernetes-deployment-manifest.example.yaml +8 -0
  42. package/assets/examples-decomposed/kubernetes-deployment-manifest.md +237 -0
  43. package/assets/examples-decomposed/kubernetes-deployment-manifest.specly +41 -0
  44. package/assets/templates/README.md +559 -0
  45. package/assets/templates/TEMPLATE-ENHANCEMENTS-V33.md +462 -0
  46. package/assets/templates/backend-only/CLAUDE.md +73 -0
  47. package/assets/templates/backend-only/README.md +197 -0
  48. package/assets/templates/backend-only/deployments/README.md +149 -0
  49. package/assets/templates/backend-only/deployments/development.specly +53 -0
  50. package/assets/templates/backend-only/deployments/production.specly +87 -0
  51. package/assets/templates/backend-only/docs/README.md +50 -0
  52. package/assets/templates/backend-only/docs/api/README.md +7 -0
  53. package/assets/templates/backend-only/docs/diagrams/README.md +85 -0
  54. package/assets/templates/backend-only/docs/example-documentation-template.md +269 -0
  55. package/assets/templates/backend-only/docs/guides/README.md +15 -0
  56. package/assets/templates/backend-only/dot.env.example +18 -0
  57. package/assets/templates/backend-only/generated/README.md +56 -0
  58. package/assets/templates/backend-only/generated/code/integration-test.template.js +320 -0
  59. package/assets/templates/backend-only/generated/code/package.json.template +34 -0
  60. package/assets/templates/backend-only/generated/docs/README.md +49 -0
  61. package/assets/templates/backend-only/gitignore +54 -0
  62. package/assets/templates/backend-only/manifests/README.md +72 -0
  63. package/assets/templates/backend-only/manifests/docker-compose.specly +91 -0
  64. package/assets/templates/backend-only/manifests/implementation.yaml +100 -0
  65. package/assets/templates/backend-only/manifests/kubernetes.specly +140 -0
  66. package/assets/templates/backend-only/package.json +59 -0
  67. package/assets/templates/backend-only/scripts/test-all.sh +160 -0
  68. package/assets/templates/backend-only/scripts/test-generated-code.sh +165 -0
  69. package/assets/templates/backend-only/specs/main.specly +67 -0
  70. package/assets/templates/default/CLAUDE.md +141 -0
  71. package/assets/templates/default/README.md +404 -0
  72. package/assets/templates/default/deployments/README.md +149 -0
  73. package/assets/templates/default/deployments/development.specly +53 -0
  74. package/assets/templates/default/deployments/production.specly +87 -0
  75. package/assets/templates/default/docs/README.md +50 -0
  76. package/assets/templates/default/docs/api/README.md +7 -0
  77. package/assets/templates/default/docs/diagrams/README.md +85 -0
  78. package/assets/templates/default/docs/example-documentation-template.md +269 -0
  79. package/assets/templates/default/docs/guides/README.md +15 -0
  80. package/assets/templates/default/dot.env.example +18 -0
  81. package/assets/templates/default/generated/README.md +56 -0
  82. package/assets/templates/default/generated/code/integration-test.template.js +320 -0
  83. package/assets/templates/default/generated/code/package.json.template +34 -0
  84. package/assets/templates/default/generated/docs/README.md +49 -0
  85. package/assets/templates/default/gitignore +54 -0
  86. package/assets/templates/default/manifests/README.md +72 -0
  87. package/assets/templates/default/manifests/docker-compose.specly +91 -0
  88. package/assets/templates/default/manifests/implementation.yaml +176 -0
  89. package/assets/templates/default/manifests/kubernetes.specly +140 -0
  90. package/assets/templates/default/package.json +61 -0
  91. package/assets/templates/default/scripts/test-all.sh +160 -0
  92. package/assets/templates/default/scripts/test-generated-code.sh +165 -0
  93. package/assets/templates/default/specs/main.specly +67 -0
  94. package/assets/templates/frontend-only/CLAUDE.md +75 -0
  95. package/assets/templates/frontend-only/README.md +231 -0
  96. package/assets/templates/frontend-only/deployments/README.md +149 -0
  97. package/assets/templates/frontend-only/deployments/development.specly +53 -0
  98. package/assets/templates/frontend-only/deployments/production.specly +87 -0
  99. package/assets/templates/frontend-only/docs/README.md +50 -0
  100. package/assets/templates/frontend-only/docs/api/README.md +7 -0
  101. package/assets/templates/frontend-only/docs/diagrams/README.md +85 -0
  102. package/assets/templates/frontend-only/docs/example-documentation-template.md +269 -0
  103. package/assets/templates/frontend-only/docs/guides/README.md +15 -0
  104. package/assets/templates/frontend-only/dot.env.example +18 -0
  105. package/assets/templates/frontend-only/generated/README.md +56 -0
  106. package/assets/templates/frontend-only/generated/code/integration-test.template.js +320 -0
  107. package/assets/templates/frontend-only/generated/code/package.json.template +34 -0
  108. package/assets/templates/frontend-only/generated/docs/README.md +49 -0
  109. package/assets/templates/frontend-only/gitignore +54 -0
  110. package/assets/templates/frontend-only/manifests/README.md +72 -0
  111. package/assets/templates/frontend-only/manifests/docker-compose.specly +91 -0
  112. package/assets/templates/frontend-only/manifests/implementation.yaml +58 -0
  113. package/assets/templates/frontend-only/manifests/kubernetes.specly +140 -0
  114. package/assets/templates/frontend-only/package.json +59 -0
  115. package/assets/templates/frontend-only/scripts/test-all.sh +160 -0
  116. package/assets/templates/frontend-only/scripts/test-generated-code.sh +165 -0
  117. package/assets/templates/frontend-only/specs/main.specly +57 -0
  118. package/assets/templates/full-stack/AI-GUIDE.md +60 -0
  119. package/assets/templates/full-stack/CLAUDE.md +141 -0
  120. package/assets/templates/full-stack/README.md +382 -0
  121. package/assets/templates/full-stack/archive/AI-GUIDE-legacy.md +392 -0
  122. package/assets/templates/full-stack/deployments/README.md +149 -0
  123. package/assets/templates/full-stack/deployments/development.specly +53 -0
  124. package/assets/templates/full-stack/deployments/production.specly +87 -0
  125. package/assets/templates/full-stack/docs/README.md +51 -0
  126. package/assets/templates/full-stack/docs/api/README.md +7 -0
  127. package/assets/templates/full-stack/docs/diagrams/README.md +85 -0
  128. package/assets/templates/full-stack/docs/example-documentation-template.md +269 -0
  129. package/assets/templates/full-stack/docs/guides/README.md +15 -0
  130. package/assets/templates/full-stack/generated/README.md +56 -0
  131. package/assets/templates/full-stack/generated/code/integration-test.template.js +320 -0
  132. package/assets/templates/full-stack/generated/code/package.json.template +34 -0
  133. package/assets/templates/full-stack/generated/docs/README.md +49 -0
  134. package/assets/templates/full-stack/gitignore +54 -0
  135. package/assets/templates/full-stack/manifests/README.md +72 -0
  136. package/assets/templates/full-stack/manifests/docker-compose.specly +91 -0
  137. package/assets/templates/full-stack/manifests/implementation.yaml +155 -0
  138. package/assets/templates/full-stack/manifests/kubernetes.specly +140 -0
  139. package/assets/templates/full-stack/package.json +45 -0
  140. package/assets/templates/full-stack/scripts/test-all.sh +160 -0
  141. package/assets/templates/full-stack/scripts/test-generated-code.sh +165 -0
  142. package/assets/templates/full-stack/specs/example-v33.specly +297 -0
  143. package/assets/templates/full-stack/specs/main-simple.specly +73 -0
  144. package/assets/templates/full-stack/specs/main.specly +408 -0
  145. package/dist/engines/code-generator.d.ts +86 -0
  146. package/dist/engines/code-generator.d.ts.map +1 -0
  147. package/dist/engines/code-generator.js +159 -0
  148. package/dist/engines/code-generator.js.map +1 -0
  149. package/dist/engines/engine-registry.d.ts +94 -0
  150. package/dist/engines/engine-registry.d.ts.map +1 -0
  151. package/dist/engines/engine-registry.js +163 -0
  152. package/dist/engines/engine-registry.js.map +1 -0
  153. package/dist/engines/index.d.ts +10 -0
  154. package/dist/engines/index.d.ts.map +1 -0
  155. package/dist/engines/index.js +12 -0
  156. package/dist/engines/index.js.map +1 -0
  157. package/dist/engines/typescript-engine.d.ts +74 -0
  158. package/dist/engines/typescript-engine.d.ts.map +1 -0
  159. package/dist/engines/typescript-engine.js +288 -0
  160. package/dist/engines/typescript-engine.js.map +1 -0
  161. package/dist/generators/index.d.ts +11 -0
  162. package/dist/generators/index.d.ts.map +1 -0
  163. package/dist/generators/index.js +11 -0
  164. package/dist/generators/index.js.map +1 -0
  165. package/dist/index.d.ts +48 -0
  166. package/dist/index.d.ts.map +1 -0
  167. package/dist/index.js +434 -0
  168. package/dist/index.js.map +1 -0
  169. package/dist/library/index.d.ts +12 -0
  170. package/dist/library/index.d.ts.map +1 -0
  171. package/dist/library/index.js +15 -0
  172. package/dist/library/index.js.map +1 -0
  173. package/dist/library/library.d.ts +132 -0
  174. package/dist/library/library.d.ts.map +1 -0
  175. package/dist/library/library.js +343 -0
  176. package/dist/library/library.js.map +1 -0
  177. package/dist/library/loader.d.ts +73 -0
  178. package/dist/library/loader.d.ts.map +1 -0
  179. package/dist/library/loader.js +150 -0
  180. package/dist/library/loader.js.map +1 -0
  181. package/dist/library/resolver.d.ts +104 -0
  182. package/dist/library/resolver.d.ts.map +1 -0
  183. package/dist/library/resolver.js +299 -0
  184. package/dist/library/resolver.js.map +1 -0
  185. package/dist/library/validator.d.ts +65 -0
  186. package/dist/library/validator.d.ts.map +1 -0
  187. package/dist/library/validator.js +203 -0
  188. package/dist/library/validator.js.map +1 -0
  189. package/dist/types/index.d.ts +7 -0
  190. package/dist/types/index.d.ts.map +1 -0
  191. package/dist/types/index.js +7 -0
  192. package/dist/types/index.js.map +1 -0
  193. package/dist/types/instance-factory.d.ts +289 -0
  194. package/dist/types/instance-factory.d.ts.map +1 -0
  195. package/dist/types/instance-factory.js +8 -0
  196. package/dist/types/instance-factory.js.map +1 -0
  197. package/dist/types/unified-mappings.d.ts +163 -0
  198. package/dist/types/unified-mappings.d.ts.map +1 -0
  199. package/dist/types/unified-mappings.js +110 -0
  200. package/dist/types/unified-mappings.js.map +1 -0
  201. package/dist/utils/ai-spec-loader.d.ts +77 -0
  202. package/dist/utils/ai-spec-loader.d.ts.map +1 -0
  203. package/dist/utils/ai-spec-loader.js +138 -0
  204. package/dist/utils/ai-spec-loader.js.map +1 -0
  205. package/dist/utils/index.d.ts +9 -0
  206. package/dist/utils/index.d.ts.map +1 -0
  207. package/dist/utils/index.js +9 -0
  208. package/dist/utils/index.js.map +1 -0
  209. package/dist/utils/manifest-loader.d.ts +107 -0
  210. package/dist/utils/manifest-loader.d.ts.map +1 -0
  211. package/dist/utils/manifest-loader.js +168 -0
  212. package/dist/utils/manifest-loader.js.map +1 -0
  213. package/dist/utils/mapping-migration.d.ts +53 -0
  214. package/dist/utils/mapping-migration.d.ts.map +1 -0
  215. package/dist/utils/mapping-migration.js +194 -0
  216. package/dist/utils/mapping-migration.js.map +1 -0
  217. package/libs/instance-factories/CURVED-INTERFACE.md +278 -0
  218. package/libs/instance-factories/README.md +433 -0
  219. package/libs/instance-factories/applications/generic-app.yaml +52 -0
  220. package/libs/instance-factories/applications/react-app.yaml +186 -0
  221. package/libs/instance-factories/applications/templates/generic/backend-env-generator.ts +31 -0
  222. package/libs/instance-factories/applications/templates/generic/backend-package-json-generator.ts +80 -0
  223. package/libs/instance-factories/applications/templates/generic/backend-tsconfig-generator.ts +69 -0
  224. package/libs/instance-factories/applications/templates/generic/main-generator.ts +308 -0
  225. package/libs/instance-factories/applications/templates/react/_view-components-source.ts +555 -0
  226. package/libs/instance-factories/applications/templates/react/api-client-generator.ts +436 -0
  227. package/libs/instance-factories/applications/templates/react/api-types-generator.ts +153 -0
  228. package/libs/instance-factories/applications/templates/react/app-tsx-generator.ts +94 -0
  229. package/libs/instance-factories/applications/templates/react/env-example-generator.ts +24 -0
  230. package/libs/instance-factories/applications/templates/react/field-helpers-generator.ts +106 -0
  231. package/libs/instance-factories/applications/templates/react/gitignore-generator.ts +38 -0
  232. package/libs/instance-factories/applications/templates/react/index-css-generator.ts +85 -0
  233. package/libs/instance-factories/applications/templates/react/index-html-generator.ts +30 -0
  234. package/libs/instance-factories/applications/templates/react/main-tsx-generator.ts +34 -0
  235. package/libs/instance-factories/applications/templates/react/package-json-generator.ts +54 -0
  236. package/libs/instance-factories/applications/templates/react/pattern-adapter-generator.ts +179 -0
  237. package/libs/instance-factories/applications/templates/react/react-pattern-adapter.tsx +1347 -0
  238. package/libs/instance-factories/applications/templates/react/relationship-field-generator.ts +150 -0
  239. package/libs/instance-factories/applications/templates/react/tailwind-adapter-generator.ts +704 -0
  240. package/libs/instance-factories/applications/templates/react/tailwind-adapter-wrapper-generator.ts +84 -0
  241. package/libs/instance-factories/applications/templates/react/tsconfig-generator.ts +35 -0
  242. package/libs/instance-factories/applications/templates/react/use-api-hooks-generator.ts +121 -0
  243. package/libs/instance-factories/applications/templates/react/view-dashboard-generator.ts +150 -0
  244. package/libs/instance-factories/applications/templates/react/view-detail-generator.ts +150 -0
  245. package/libs/instance-factories/applications/templates/react/view-form-generator.ts +362 -0
  246. package/libs/instance-factories/applications/templates/react/view-list-generator.ts +98 -0
  247. package/libs/instance-factories/applications/templates/react/view-router-generator.ts +89 -0
  248. package/libs/instance-factories/applications/templates/react/vite-config-generator.ts +49 -0
  249. package/libs/instance-factories/archived/fastify-prisma.yaml +104 -0
  250. package/libs/instance-factories/cli/commander-js.yaml +55 -0
  251. package/libs/instance-factories/cli/templates/commander/cli-entry-generator.d.ts +12 -0
  252. package/libs/instance-factories/cli/templates/commander/cli-entry-generator.d.ts.map +1 -0
  253. package/libs/instance-factories/cli/templates/commander/cli-entry-generator.js +115 -0
  254. package/libs/instance-factories/cli/templates/commander/cli-entry-generator.js.map +1 -0
  255. package/libs/instance-factories/cli/templates/commander/cli-entry-generator.ts +145 -0
  256. package/libs/instance-factories/cli/templates/commander/command-generator.d.ts +14 -0
  257. package/libs/instance-factories/cli/templates/commander/command-generator.d.ts.map +1 -0
  258. package/libs/instance-factories/cli/templates/commander/command-generator.js +182 -0
  259. package/libs/instance-factories/cli/templates/commander/command-generator.js.map +1 -0
  260. package/libs/instance-factories/cli/templates/commander/command-generator.ts +992 -0
  261. package/libs/instance-factories/communication/event-emitter.yaml +56 -0
  262. package/libs/instance-factories/communication/rabbitmq-events.yaml +87 -0
  263. package/libs/instance-factories/communication/templates/eventemitter/bus-generator.ts +93 -0
  264. package/libs/instance-factories/communication/templates/eventemitter/publisher-generator.ts +117 -0
  265. package/libs/instance-factories/communication/templates/eventemitter/subscriber-generator.ts +101 -0
  266. package/libs/instance-factories/controllers/fastify.yaml +127 -0
  267. package/libs/instance-factories/controllers/templates/fastify/meta-routes-generator.ts +103 -0
  268. package/libs/instance-factories/controllers/templates/fastify/routes-generator.ts +389 -0
  269. package/libs/instance-factories/controllers/templates/fastify/server-generator.ts +76 -0
  270. package/libs/instance-factories/infrastructure/docker-k8s.yaml +61 -0
  271. package/libs/instance-factories/infrastructure/templates/docker-k8s/infrastructure-generator.ts +46 -0
  272. package/libs/instance-factories/orms/prisma.yaml +89 -0
  273. package/libs/instance-factories/orms/templates/prisma/schema-generator.ts +563 -0
  274. package/libs/instance-factories/orms/templates/prisma/services-generator.ts +408 -0
  275. package/libs/instance-factories/scaffolding/generic-scaffold.yaml +65 -0
  276. package/libs/instance-factories/scaffolding/templates/generic/env-example-generator.ts +73 -0
  277. package/libs/instance-factories/scaffolding/templates/generic/env-generator.ts +85 -0
  278. package/libs/instance-factories/scaffolding/templates/generic/gitignore-generator.ts +69 -0
  279. package/libs/instance-factories/scaffolding/templates/generic/package-json-generator.ts +176 -0
  280. package/libs/instance-factories/scaffolding/templates/generic/readme-generator.ts +207 -0
  281. package/libs/instance-factories/scaffolding/templates/generic/tsconfig-generator.ts +78 -0
  282. package/libs/instance-factories/scaffolding/templates/generic/tsconfig-react-generator.ts +41 -0
  283. package/libs/instance-factories/sdks/python-sdk.yaml +66 -0
  284. package/libs/instance-factories/sdks/templates/python/sdk-generator.ts +50 -0
  285. package/libs/instance-factories/sdks/templates/typescript/sdk-generator.ts +49 -0
  286. package/libs/instance-factories/sdks/typescript-sdk.yaml +59 -0
  287. package/libs/instance-factories/services/prisma-services.yaml +71 -0
  288. package/libs/instance-factories/services/templates/prisma/behavior-generator.ts +303 -0
  289. package/libs/instance-factories/services/templates/prisma/controller-generator.ts +532 -0
  290. package/libs/instance-factories/services/templates/prisma/service-generator.ts +315 -0
  291. package/libs/instance-factories/shared/path-resolver.ts +111 -0
  292. package/libs/instance-factories/storage/mongodb.yaml +79 -0
  293. package/libs/instance-factories/storage/postgresql.yaml +75 -0
  294. package/libs/instance-factories/storage/redis.yaml +79 -0
  295. package/libs/instance-factories/storage/templates/mongodb/config-generator.ts +15 -0
  296. package/libs/instance-factories/storage/templates/mongodb/docker-generator.ts +18 -0
  297. package/libs/instance-factories/storage/templates/postgresql/config-generator.ts +54 -0
  298. package/libs/instance-factories/storage/templates/postgresql/docker-generator.ts +55 -0
  299. package/libs/instance-factories/storage/templates/redis/config-generator.ts +16 -0
  300. package/libs/instance-factories/storage/templates/redis/docker-generator.ts +18 -0
  301. package/libs/instance-factories/test-generation.ts +192 -0
  302. package/libs/instance-factories/testing/templates/vitest/tests-generator.ts +51 -0
  303. package/libs/instance-factories/testing/vitest-tests.yaml +63 -0
  304. package/libs/instance-factories/tools/templates/mcp/mcp-server-generator.ts +136 -0
  305. package/libs/instance-factories/tools/templates/mcp/static/docs/DEPLOYMENT_GUIDE.md +630 -0
  306. package/libs/instance-factories/tools/templates/mcp/static/docs/HYBRID_RESOURCE_SYSTEM.md +330 -0
  307. package/libs/instance-factories/tools/templates/mcp/static/docs/deployments/EXTENSION_DEPLOYMENT.md +552 -0
  308. package/libs/instance-factories/tools/templates/mcp/static/docs/deployments/LOCAL_DEPLOYMENT.md +164 -0
  309. package/libs/instance-factories/tools/templates/mcp/static/docs/deployments/WEB_DEPLOYMENT.md +247 -0
  310. package/libs/instance-factories/tools/templates/mcp/static/package.json +92 -0
  311. package/libs/instance-factories/tools/templates/mcp/static/scripts/build-enterprise.js +284 -0
  312. package/libs/instance-factories/tools/templates/mcp/static/scripts/build-extension.js +139 -0
  313. package/libs/instance-factories/tools/templates/mcp/static/scripts/build-local.js +74 -0
  314. package/libs/instance-factories/tools/templates/mcp/static/scripts/build-web.js +156 -0
  315. package/libs/instance-factories/tools/templates/mcp/static/scripts/copy-canonical-files.js +41 -0
  316. package/libs/instance-factories/tools/templates/mcp/static/scripts/test-deployments.js +259 -0
  317. package/libs/instance-factories/tools/templates/mcp/static/scripts/test-hybrid-resources.js +231 -0
  318. package/libs/instance-factories/tools/templates/mcp/static/scripts/test-hybrid-simple.js +196 -0
  319. package/libs/instance-factories/tools/templates/mcp/static/src/controllers/MCPServerController.ts +293 -0
  320. package/libs/instance-factories/tools/templates/mcp/static/src/events/EventEmitter.ts +90 -0
  321. package/libs/instance-factories/tools/templates/mcp/static/src/index.ts +24 -0
  322. package/libs/instance-factories/tools/templates/mcp/static/src/interfaces/ResourceProvider.ts +15 -0
  323. package/libs/instance-factories/tools/templates/mcp/static/src/models/LibrarySuggestion.ts +106 -0
  324. package/libs/instance-factories/tools/templates/mcp/static/src/models/SpecVerseResource.ts +75 -0
  325. package/libs/instance-factories/tools/templates/mcp/static/src/server/mcp-server.ts +239 -0
  326. package/libs/instance-factories/tools/templates/mcp/static/src/services/CLIProxyService.ts +1501 -0
  327. package/libs/instance-factories/tools/templates/mcp/static/src/services/EmbeddedResourcesAdapter.ts +211 -0
  328. package/libs/instance-factories/tools/templates/mcp/static/src/services/EntityModuleService.ts +308 -0
  329. package/libs/instance-factories/tools/templates/mcp/static/src/services/HybridResourcesProvider.ts +210 -0
  330. package/libs/instance-factories/tools/templates/mcp/static/src/services/LibraryToolsService.ts +356 -0
  331. package/libs/instance-factories/tools/templates/mcp/static/src/services/OrchestratorBridge.ts +524 -0
  332. package/libs/instance-factories/tools/templates/mcp/static/src/services/OrchestratorToolsService.ts +530 -0
  333. package/libs/instance-factories/tools/templates/mcp/static/src/services/PromptToolsService.ts +594 -0
  334. package/libs/instance-factories/tools/templates/mcp/static/src/services/ResourcesProviderService.ts +170 -0
  335. package/libs/instance-factories/tools/templates/mcp/static/src/tests/unit/CLIProxyService.init.test.ts +544 -0
  336. package/libs/instance-factories/tools/templates/mcp/static/src/tests/unit/CLIProxyService.test.ts +189 -0
  337. package/libs/instance-factories/tools/templates/mcp/static/src/tests/unit/ResourcesProviderService.test.ts +89 -0
  338. package/libs/instance-factories/tools/templates/mcp/static/src/types/index.ts +110 -0
  339. package/libs/instance-factories/tools/templates/mcp/static/tsconfig.json +28 -0
  340. package/libs/instance-factories/tools/templates/vscode/static/extension.ts +1195 -0
  341. package/libs/instance-factories/tools/templates/vscode/static/language-configuration.json +34 -0
  342. package/libs/instance-factories/tools/templates/vscode/static/schemas/specverse-v3-schema.json +4279 -0
  343. package/libs/instance-factories/tools/templates/vscode/static/syntaxes/specverse.tmLanguage.json +138 -0
  344. package/libs/instance-factories/tools/templates/vscode/static/themes/README.md +74 -0
  345. package/libs/instance-factories/tools/templates/vscode/static/themes/complete-specverse-colors.json +122 -0
  346. package/libs/instance-factories/tools/templates/vscode/static/themes/specverse-basic-theme.json +65 -0
  347. package/libs/instance-factories/tools/templates/vscode/static/themes/specverse-complete-theme.json +123 -0
  348. package/libs/instance-factories/tools/templates/vscode/static/themes/specverse-theme-colors.json +64 -0
  349. package/libs/instance-factories/tools/templates/vscode/vscode-extension-generator.ts +214 -0
  350. package/libs/instance-factories/validation/templates/zod/validation-generator.ts +46 -0
  351. package/libs/instance-factories/validation/zod.yaml +56 -0
  352. package/libs/instance-factories/views/index.d.ts +13 -0
  353. package/libs/instance-factories/views/index.d.ts.map +1 -0
  354. package/libs/instance-factories/views/index.js +18 -0
  355. package/libs/instance-factories/views/index.js.map +1 -0
  356. package/libs/instance-factories/views/index.ts +45 -0
  357. package/libs/instance-factories/views/react-components.yaml +129 -0
  358. package/libs/instance-factories/views/templates/ARCHITECTURE.md +198 -0
  359. package/libs/instance-factories/views/templates/react/adapters/antd-adapter.ts +869 -0
  360. package/libs/instance-factories/views/templates/react/adapters/mui-adapter.ts +953 -0
  361. package/libs/instance-factories/views/templates/react/adapters/shadcn-adapter.ts +806 -0
  362. package/libs/instance-factories/views/templates/react/app-generator.ts +55 -0
  363. package/libs/instance-factories/views/templates/react/components-generator.ts +391 -0
  364. package/libs/instance-factories/views/templates/react/forms-generator.ts +343 -0
  365. package/libs/instance-factories/views/templates/react/frontend-package-json-generator.ts +54 -0
  366. package/libs/instance-factories/views/templates/react/hooks-generator.ts +122 -0
  367. package/libs/instance-factories/views/templates/react/index-css-generator.ts +209 -0
  368. package/libs/instance-factories/views/templates/react/index-html-generator.ts +34 -0
  369. package/libs/instance-factories/views/templates/react/main-tsx-generator.ts +29 -0
  370. package/libs/instance-factories/views/templates/react/react-component-generator.d.ts +152 -0
  371. package/libs/instance-factories/views/templates/react/react-component-generator.d.ts.map +1 -0
  372. package/libs/instance-factories/views/templates/react/react-component-generator.js +398 -0
  373. package/libs/instance-factories/views/templates/react/react-component-generator.js.map +1 -0
  374. package/libs/instance-factories/views/templates/react/react-component-generator.ts +533 -0
  375. package/libs/instance-factories/views/templates/react/router-generator.ts +197 -0
  376. package/libs/instance-factories/views/templates/react/router-generic-generator.ts +103 -0
  377. package/libs/instance-factories/views/templates/react/spec-json-generator.ts +17 -0
  378. package/libs/instance-factories/views/templates/react/types-generator.ts +76 -0
  379. package/libs/instance-factories/views/templates/react/views-metadata-generator.ts +42 -0
  380. package/libs/instance-factories/views/templates/react/vite-config-generator.ts +38 -0
  381. package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.d.ts.map +1 -0
  382. package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.js.map +1 -0
  383. package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.ts +474 -0
  384. package/libs/instance-factories/views/templates/shared/__tests__/composite-patterns.test.ts +242 -0
  385. package/libs/instance-factories/views/templates/shared/adapter-types.d.ts +77 -0
  386. package/libs/instance-factories/views/templates/shared/adapter-types.d.ts.map +1 -0
  387. package/libs/instance-factories/views/templates/shared/adapter-types.js +47 -0
  388. package/libs/instance-factories/views/templates/shared/adapter-types.js.map +1 -0
  389. package/libs/instance-factories/views/templates/shared/adapter-types.ts +142 -0
  390. package/libs/instance-factories/views/templates/shared/atomic-components-registry.d.ts +63 -0
  391. package/libs/instance-factories/views/templates/shared/atomic-components-registry.d.ts.map +1 -0
  392. package/libs/instance-factories/views/templates/shared/atomic-components-registry.js +822 -0
  393. package/libs/instance-factories/views/templates/shared/atomic-components-registry.js.map +1 -0
  394. package/libs/instance-factories/views/templates/shared/atomic-components-registry.ts +908 -0
  395. package/libs/instance-factories/views/templates/shared/base-generator.d.ts +247 -0
  396. package/libs/instance-factories/views/templates/shared/base-generator.d.ts.map +1 -0
  397. package/libs/instance-factories/views/templates/shared/base-generator.js +363 -0
  398. package/libs/instance-factories/views/templates/shared/base-generator.js.map +1 -0
  399. package/libs/instance-factories/views/templates/shared/base-generator.ts +608 -0
  400. package/libs/instance-factories/views/templates/shared/component-metadata.d.ts +254 -0
  401. package/libs/instance-factories/views/templates/shared/component-metadata.d.ts.map +1 -0
  402. package/libs/instance-factories/views/templates/shared/component-metadata.js +602 -0
  403. package/libs/instance-factories/views/templates/shared/component-metadata.js.map +1 -0
  404. package/libs/instance-factories/views/templates/shared/component-metadata.ts +803 -0
  405. package/libs/instance-factories/views/templates/shared/composite-pattern-types.ts +250 -0
  406. package/libs/instance-factories/views/templates/shared/composite-patterns.ts +535 -0
  407. package/libs/instance-factories/views/templates/shared/index.ts +68 -0
  408. package/libs/instance-factories/views/templates/shared/pattern-validator.ts +279 -0
  409. package/libs/instance-factories/views/templates/shared/property-mapper.d.ts +149 -0
  410. package/libs/instance-factories/views/templates/shared/property-mapper.d.ts.map +1 -0
  411. package/libs/instance-factories/views/templates/shared/property-mapper.js +580 -0
  412. package/libs/instance-factories/views/templates/shared/property-mapper.js.map +1 -0
  413. package/libs/instance-factories/views/templates/shared/property-mapper.ts +700 -0
  414. package/libs/instance-factories/views/templates/shared/syntax-mapper.d.ts +143 -0
  415. package/libs/instance-factories/views/templates/shared/syntax-mapper.d.ts.map +1 -0
  416. package/libs/instance-factories/views/templates/shared/syntax-mapper.js +420 -0
  417. package/libs/instance-factories/views/templates/shared/syntax-mapper.js.map +1 -0
  418. package/libs/instance-factories/views/templates/shared/syntax-mapper.ts +539 -0
  419. package/package.json +42 -0
  420. package/schema/SPECVERSE-SCHEMA.json +4274 -0
@@ -0,0 +1,1195 @@
1
+ /**
2
+ * SpecVerse v3.5 VS Code Extension
3
+ *
4
+ * Provides language support for SpecVerse v3.5 .specly files (YAML + Conventions + AI Inference)
5
+ */
6
+
7
+ import * as vscode from 'vscode';
8
+ import * as yaml from 'js-yaml';
9
+ import { readFileSync, existsSync } from 'fs';
10
+ import { join, dirname, basename, extname } from 'path';
11
+ import { exec } from 'child_process';
12
+ import { promisify } from 'util';
13
+
14
+ const execAsync = promisify(exec);
15
+
16
+ export function activate(context: vscode.ExtensionContext) {
17
+ console.log('SpecVerse v3.5 extension activated');
18
+
19
+ // Register providers
20
+ const provider = new SpecVerseProvider(context);
21
+
22
+ // Diagnostics collection
23
+ const diagnostics = vscode.languages.createDiagnosticCollection('specverse');
24
+ context.subscriptions.push(diagnostics);
25
+
26
+ // Document validation on save
27
+ const onSaveListener = vscode.workspace.onDidSaveTextDocument(async (document) => {
28
+ if (isSpecVerseDocument(document)) {
29
+ const config = vscode.workspace.getConfiguration('specverse');
30
+ if (config.get('validation.onSave')) {
31
+ await validateDocument(document, diagnostics);
32
+ }
33
+
34
+ if (config.get('diagrams.autoGenerate')) {
35
+ await generateDiagramForDocument(document);
36
+ }
37
+ }
38
+ });
39
+ context.subscriptions.push(onSaveListener);
40
+
41
+ // Document validation on change (debounced)
42
+ let validationTimeout: NodeJS.Timeout;
43
+ const onChangeListener = vscode.workspace.onDidChangeTextDocument((event) => {
44
+ const document = event.document;
45
+ if (isSpecVerseDocument(document)) {
46
+ clearTimeout(validationTimeout);
47
+ validationTimeout = setTimeout(async () => {
48
+ const config = vscode.workspace.getConfiguration('specverse');
49
+ if (config.get('validation.enabled')) {
50
+ await validateDocument(document, diagnostics);
51
+ }
52
+ }, 1000);
53
+ }
54
+ });
55
+ context.subscriptions.push(onChangeListener);
56
+
57
+ // Register auto-generated CLI commands dynamically
58
+ const packageJson = require('../package.json');
59
+ const autoGeneratedCommands = packageJson.contributes.commands
60
+ .filter((cmd: any) => cmd.command.startsWith('specverse.'))
61
+ .map((cmd: any) => {
62
+ const commandName = cmd.command.replace('specverse.', '');
63
+ return vscode.commands.registerCommand(cmd.command, async (uri?: vscode.Uri) => {
64
+ const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
65
+ if (document && isSpecVerseDocument(document)) {
66
+ await executeCliCommand(document, commandName);
67
+ }
68
+ });
69
+ });
70
+
71
+ // Register manual/custom commands
72
+ const commands = [
73
+ vscode.commands.registerCommand('specverse.validate', async (uri?: vscode.Uri) => {
74
+ const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
75
+ if (document && isSpecVerseDocument(document)) {
76
+ await validateDocument(document, diagnostics);
77
+ vscode.window.showInformationMessage('SpecVerse validation completed');
78
+ }
79
+ }),
80
+
81
+ vscode.commands.registerCommand('specverse.format', async () => {
82
+ const editor = vscode.window.activeTextEditor;
83
+ if (editor && isSpecVerseDocument(editor.document)) {
84
+ await formatDocument(editor);
85
+ }
86
+ }),
87
+
88
+ vscode.commands.registerCommand('specverse.generateDiagram', async (uri?: vscode.Uri) => {
89
+ const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
90
+ if (document && isSpecVerseDocument(document)) {
91
+ await generateDiagramForDocument(document);
92
+ }
93
+ }),
94
+
95
+ vscode.commands.registerCommand('specverse.generateDocs', async (uri?: vscode.Uri) => {
96
+ const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
97
+ if (document && isSpecVerseDocument(document)) {
98
+ await generateDocsForDocument(document);
99
+ }
100
+ }),
101
+
102
+ vscode.commands.registerCommand('specverse.generateAI', async (uri?: vscode.Uri) => {
103
+ const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
104
+ if (document && isSpecVerseDocument(document)) {
105
+ await generateAIForDocument(document);
106
+ }
107
+ }),
108
+
109
+ vscode.commands.registerCommand('specverse.processSpecly', async (uri?: vscode.Uri) => {
110
+ const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
111
+ if (document && document.fileName.endsWith('.specly')) {
112
+ await processSpeclyDocument(document);
113
+ } else {
114
+ vscode.window.showErrorMessage('This command only works with .specly files');
115
+ }
116
+ }),
117
+
118
+ vscode.commands.registerCommand('specverse.infer', async (uri?: vscode.Uri) => {
119
+ const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
120
+ if (document && isSpecVerseDocument(document)) {
121
+ await inferCompleteSystemForDocument(document);
122
+ }
123
+ }),
124
+
125
+ vscode.commands.registerCommand('specverse.testCycle', async (uri?: vscode.Uri) => {
126
+ const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
127
+ if (document && isSpecVerseDocument(document)) {
128
+ await runTestCycleForDocument(document);
129
+ }
130
+ }),
131
+
132
+ vscode.commands.registerCommand('specverse.batchGenerate', async () => {
133
+ await runBatchDiagramGeneration();
134
+ }),
135
+
136
+ vscode.commands.registerCommand('specverse.migrate', async (uri?: vscode.Uri) => {
137
+ // Determine the directory to migrate
138
+ let targetDir: string;
139
+
140
+ if (uri) {
141
+ // URI provided - could be file or folder
142
+ const stat = await vscode.workspace.fs.stat(uri);
143
+ if (stat.type === vscode.FileType.Directory) {
144
+ targetDir = uri.fsPath;
145
+ } else {
146
+ // It's a file - use its parent directory
147
+ targetDir = dirname(uri.fsPath);
148
+ }
149
+ } else if (vscode.window.activeTextEditor) {
150
+ // No URI - use active editor's directory
151
+ targetDir = dirname(vscode.window.activeTextEditor.document.fileName);
152
+ } else if (vscode.workspace.workspaceFolders?.[0]) {
153
+ // Fallback to workspace root
154
+ targetDir = vscode.workspace.workspaceFolders[0].uri.fsPath;
155
+ } else {
156
+ vscode.window.showErrorMessage('No directory to migrate. Open a file or folder first.');
157
+ return;
158
+ }
159
+
160
+ await runMigrateCommand(targetDir);
161
+ })
162
+ ];
163
+
164
+ context.subscriptions.push(...commands, ...autoGeneratedCommands);
165
+
166
+ // Register completion provider for .specly files
167
+ const completionProvider = vscode.languages.registerCompletionItemProvider(
168
+ { scheme: 'file', language: 'specly' },
169
+ new SpecVerseCompletionProvider(),
170
+ ':',
171
+ ' '
172
+ );
173
+ context.subscriptions.push(completionProvider);
174
+
175
+ // Register hover provider for .specly files
176
+ const hoverProvider = vscode.languages.registerHoverProvider(
177
+ { scheme: 'file', language: 'specly' },
178
+ new SpecVerseHoverProvider()
179
+ );
180
+ context.subscriptions.push(hoverProvider);
181
+
182
+ // Status bar
183
+ const statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
184
+ statusBar.command = 'specverse.validate';
185
+ context.subscriptions.push(statusBar);
186
+
187
+ // Update status bar on active editor change
188
+ const onActiveEditorChange = vscode.window.onDidChangeActiveTextEditor((editor) => {
189
+ if (editor && isSpecVerseDocument(editor.document)) {
190
+ statusBar.text = '$(check) SpecVerse';
191
+ statusBar.tooltip = 'Click to validate SpecVerse file';
192
+ statusBar.show();
193
+ } else {
194
+ statusBar.hide();
195
+ }
196
+ });
197
+ context.subscriptions.push(onActiveEditorChange);
198
+
199
+ // Initial status bar update
200
+ if (vscode.window.activeTextEditor && isSpecVerseDocument(vscode.window.activeTextEditor.document)) {
201
+ statusBar.text = '$(check) SpecVerse';
202
+ statusBar.tooltip = 'Click to validate SpecVerse file';
203
+ statusBar.show();
204
+ }
205
+ }
206
+
207
+ class SpecVerseProvider {
208
+ constructor(private context: vscode.ExtensionContext) {}
209
+
210
+ getCliPath(): string {
211
+ const config = vscode.workspace.getConfiguration('specverse');
212
+ return config.get('cli.path') || 'specverse';
213
+ }
214
+ }
215
+
216
+ class SpecVerseCompletionProvider implements vscode.CompletionItemProvider {
217
+ provideCompletionItems(
218
+ document: vscode.TextDocument,
219
+ position: vscode.Position,
220
+ token: vscode.CancellationToken,
221
+ context: vscode.CompletionContext
222
+ ): vscode.ProviderResult<vscode.CompletionItem[] | vscode.CompletionList<vscode.CompletionItem>> {
223
+
224
+ if (!isSpecVerseDocument(document)) {
225
+ return [];
226
+ }
227
+
228
+ const line = document.lineAt(position).text;
229
+ const linePrefix = line.substring(0, position.character);
230
+
231
+ // Detect context
232
+ const context_info = analyzeContext(document, position);
233
+
234
+ const completions: vscode.CompletionItem[] = [];
235
+
236
+ // Type completions for attributes
237
+ if (context_info.isAttributeType) {
238
+ const types = [
239
+ 'String', 'Text', 'Integer', 'Number', 'Boolean',
240
+ 'Date', 'DateTime', 'UUID', 'Email', 'URL',
241
+ 'JSON', 'Object', 'Array'
242
+ ];
243
+
244
+ types.forEach(type => {
245
+ const item = new vscode.CompletionItem(type, vscode.CompletionItemKind.TypeParameter);
246
+ item.documentation = new vscode.MarkdownString(`SpecVerse type: \`${type}\``);
247
+ completions.push(item);
248
+ });
249
+ }
250
+
251
+ // Modifier completions
252
+ if (context_info.isModifier) {
253
+ const modifiers = [
254
+ { name: 'required', description: 'Field is required' },
255
+ { name: 'unique', description: 'Field must be unique' },
256
+ { name: 'searchable', description: 'Field is searchable' },
257
+ { name: 'verified', description: 'Field requires verification' },
258
+ { name: 'auto=uuid4', description: 'Auto-generate UUID' },
259
+ { name: 'auto=now', description: 'Auto-set current timestamp' },
260
+ { name: 'auto=token', description: 'Auto-generate token' },
261
+ { name: 'default=', description: 'Default value' },
262
+ { name: 'min=', description: 'Minimum value' },
263
+ { name: 'max=', description: 'Maximum value' }
264
+ ];
265
+
266
+ modifiers.forEach(mod => {
267
+ const item = new vscode.CompletionItem(mod.name, vscode.CompletionItemKind.Keyword);
268
+ item.documentation = new vscode.MarkdownString(mod.description);
269
+ if (mod.name.endsWith('=')) {
270
+ item.insertText = mod.name;
271
+ item.command = { command: 'editor.action.triggerSuggest', title: 'Trigger Suggest' };
272
+ }
273
+ completions.push(item);
274
+ });
275
+ }
276
+
277
+ // Relationship type completions
278
+ if (context_info.isRelationshipType) {
279
+ const relationships = [
280
+ { name: 'hasMany', description: 'One-to-many relationship' },
281
+ { name: 'hasOne', description: 'One-to-one relationship' },
282
+ { name: 'belongsTo', description: 'Many-to-one relationship' },
283
+ { name: 'manyToMany', description: 'Many-to-many relationship' }
284
+ ];
285
+
286
+ relationships.forEach(rel => {
287
+ const item = new vscode.CompletionItem(rel.name, vscode.CompletionItemKind.Keyword);
288
+ item.documentation = new vscode.MarkdownString(rel.description);
289
+ completions.push(item);
290
+ });
291
+ }
292
+
293
+ // Section completions
294
+ if (context_info.isTopLevel) {
295
+ const sections = [
296
+ // v3.5 container format
297
+ 'components', 'deployments',
298
+ // Component-level sections
299
+ 'component', 'deployment', 'version', 'description', 'tags',
300
+ 'import', 'export', 'models', 'controllers', 'services',
301
+ 'views', 'events',
302
+ // v3.5 CURED operations
303
+ 'cured',
304
+ // Deployment sections
305
+ 'instances', 'environment', 'communications',
306
+ // v3.5 advanced features
307
+ 'profiles', 'profile-attachment', 'steps', 'subscribes_to'
308
+ ];
309
+
310
+ sections.forEach(section => {
311
+ const item = new vscode.CompletionItem(section, vscode.CompletionItemKind.Module);
312
+ if (section === 'components') {
313
+ item.documentation = new vscode.MarkdownString(`SpecVerse v3.5 container format: array of components`);
314
+ } else if (section === 'deployments') {
315
+ item.documentation = new vscode.MarkdownString(`SpecVerse v3.5 container format: array of deployments`);
316
+ } else if (section === 'cured') {
317
+ item.documentation = new vscode.MarkdownString(`SpecVerse v3.5 CURED operations: Create, Update, Retrieve, Evolve, Destroy`);
318
+ } else if (section === 'instances') {
319
+ item.documentation = new vscode.MarkdownString(`SpecVerse v3.5 deployment instances: controllers, services, views, communications`);
320
+ } else if (section === 'communications') {
321
+ item.documentation = new vscode.MarkdownString(`SpecVerse v3.5 communication channels: pubsub, rpc, queue, streaming`);
322
+ } else {
323
+ item.documentation = new vscode.MarkdownString(`SpecVerse section: \`${section}\``);
324
+ }
325
+ completions.push(item);
326
+ });
327
+ }
328
+
329
+ // Deployment property completions
330
+ if (context_info.isDeploymentProperty) {
331
+ const deploymentProps = [
332
+ { name: 'component', description: 'Component reference for this instance' },
333
+ { name: 'namespace', description: 'Logical namespace for this instance' },
334
+ { name: 'advertises', description: 'Capabilities this instance advertises' },
335
+ { name: 'uses', description: 'Capabilities this instance uses' },
336
+ { name: 'scale', description: 'Number of instances to run' },
337
+ { name: 'capabilities', description: 'Available capabilities on communication channel' },
338
+ { name: 'type', description: 'Communication channel type (pubsub, rpc, queue, streaming)' }
339
+ ];
340
+
341
+ deploymentProps.forEach(prop => {
342
+ const item = new vscode.CompletionItem(prop.name, vscode.CompletionItemKind.Property);
343
+ item.documentation = new vscode.MarkdownString(prop.description);
344
+ completions.push(item);
345
+ });
346
+ }
347
+
348
+ return completions;
349
+ }
350
+ }
351
+
352
+ class SpecVerseHoverProvider implements vscode.HoverProvider {
353
+ provideHover(
354
+ document: vscode.TextDocument,
355
+ position: vscode.Position,
356
+ token: vscode.CancellationToken
357
+ ): vscode.ProviderResult<vscode.Hover> {
358
+
359
+ if (!isSpecVerseDocument(document)) {
360
+ return;
361
+ }
362
+
363
+ const line = document.lineAt(position).text;
364
+ const wordRange = document.getWordRangeAtPosition(position);
365
+ const word = wordRange ? document.getText(wordRange) : '';
366
+
367
+ // Detect attribute definitions
368
+ const attributeMatch = line.match(/^\s*(\w+):\s*(\w+)(.*)/);
369
+ if (attributeMatch && wordRange) {
370
+ const [, name, type, modifiers] = attributeMatch;
371
+
372
+ if (word === type) {
373
+ return new vscode.Hover([
374
+ `**SpecVerse Type:** \`${type}\``,
375
+ '',
376
+ getTypeDocumentation(type)
377
+ ]);
378
+ }
379
+
380
+ if (word === name) {
381
+ return new vscode.Hover([
382
+ `**Attribute:** \`${name}\``,
383
+ `**Type:** \`${type}\``,
384
+ `**Modifiers:** \`${modifiers.trim() || 'none'}\``,
385
+ '',
386
+ 'SpecVerse attribute definition using conventions'
387
+ ]);
388
+ }
389
+ }
390
+
391
+ // Detect lifecycle flows
392
+ const flowMatch = line.match(/flow:\s*(.+)/);
393
+ if (flowMatch && line.includes(word)) {
394
+ return new vscode.Hover([
395
+ '**SpecVerse Lifecycle Flow**',
396
+ '',
397
+ 'Shorthand lifecycle definition.',
398
+ 'States are connected with `->` transitions.',
399
+ '',
400
+ 'Example: `draft -> published -> archived`'
401
+ ]);
402
+ }
403
+
404
+ // Detect executable properties keywords
405
+ if (word === 'steps') {
406
+ return new vscode.Hover([
407
+ '**Steps** *(Array<string>)*',
408
+ '',
409
+ 'Sequential steps describing the execution process.',
410
+ '',
411
+ '**Usage:** Available in behaviors, controller actions, service operations, and CURED operations.',
412
+ '',
413
+ '**Example:**',
414
+ '```yaml',
415
+ 'steps:',
416
+ ' - "Validate input data"',
417
+ ' - "Process business logic"',
418
+ ' - "Return results"',
419
+ '```'
420
+ ]);
421
+ }
422
+
423
+ if (word === 'parameters') {
424
+ return new vscode.Hover([
425
+ '**Parameters** *(Object)*',
426
+ '',
427
+ 'Input parameters for executable properties (actions, operations, behaviors).',
428
+ '',
429
+ '**Usage:** Replaces `payload:` in v3.5 - defines input data structure.',
430
+ '',
431
+ '**Example:**',
432
+ '```yaml',
433
+ 'parameters:',
434
+ ' userId: UUID required',
435
+ ' name: String required max=100',
436
+ '```'
437
+ ]);
438
+ }
439
+
440
+ if (word === 'publishes') {
441
+ return new vscode.Hover([
442
+ '**Publishes** *(Array<string>)*',
443
+ '',
444
+ 'Events published by this executable property.',
445
+ '',
446
+ '**Usage:** Replaces `events:` in v3.5 - defines output events.',
447
+ '',
448
+ '**Example:**',
449
+ '```yaml',
450
+ 'publishes: [UserCreated, EmailSent]',
451
+ '```'
452
+ ]);
453
+ }
454
+
455
+ if (word === 'subscribes_to') {
456
+ return new vscode.Hover([
457
+ '**Subscribes To** *(Array<string> | Object)*',
458
+ '',
459
+ 'Events this component subscribes to.',
460
+ '',
461
+ '**Formats:**',
462
+ '- Array: `["EventName1", "EventName2"]`',
463
+ '- Object: `EventName: "handlerMethod"`',
464
+ '',
465
+ '**Example:**',
466
+ '```yaml',
467
+ 'subscribes_to:',
468
+ ' - UserCreated',
469
+ ' - OrderPlaced',
470
+ '```'
471
+ ]);
472
+ }
473
+
474
+ if (word === 'profiles') {
475
+ return new vscode.Hover([
476
+ '**Profiles** *(Array<string>)*',
477
+ '',
478
+ 'Runtime profiles that can be applied to models.',
479
+ '',
480
+ '**Usage:** Defines which profiles are available for profile attachment.',
481
+ '',
482
+ '**Example:**',
483
+ '```yaml',
484
+ 'profiles: ["CustomerProfile", "AdminProfile"]',
485
+ '```'
486
+ ]);
487
+ }
488
+
489
+ if (word === 'profile-attachment') {
490
+ return new vscode.Hover([
491
+ '**Profile Attachment** *(Object)*',
492
+ '',
493
+ 'Configuration for attaching profiles to models at runtime.',
494
+ '',
495
+ '**Properties:**',
496
+ '- `profiles`: Array of available profiles',
497
+ '- `conditions`: Optional conditions for attachment',
498
+ '- `priority`: Attachment priority (1-10)',
499
+ '',
500
+ '**Example:**',
501
+ '```yaml',
502
+ 'profile-attachment:',
503
+ ' profiles: ["VisibilityProfile"]',
504
+ ' conditions: ["user.role === admin"]',
505
+ ' priority: 5',
506
+ '```'
507
+ ]);
508
+ }
509
+
510
+ // Detect deployment keywords
511
+ if (word === 'instances') {
512
+ return new vscode.Hover([
513
+ '**Instances** *(Object)*',
514
+ '',
515
+ 'Logical deployment instances for controllers, services, views, and communications.',
516
+ '',
517
+ '**Structure:**',
518
+ '- `controllers`: Controller instance configurations',
519
+ '- `services`: Service instance configurations',
520
+ '- `views`: View instance configurations',
521
+ '- `communications`: Communication channel definitions'
522
+ ]);
523
+ }
524
+
525
+ if (word === 'advertises') {
526
+ return new vscode.Hover([
527
+ '**Advertises** *(string | Array<string>)*',
528
+ '',
529
+ 'Capabilities that this instance makes available to other instances.',
530
+ '',
531
+ '**Common patterns:**',
532
+ '- `"*"` - All capabilities',
533
+ '- `"behaviors.*"` - All behavior capabilities',
534
+ '- `["create", "read", "update"]` - Specific operations'
535
+ ]);
536
+ }
537
+
538
+ if (word === 'uses') {
539
+ return new vscode.Hover([
540
+ '**Uses** *(Array<string>)*',
541
+ '',
542
+ 'Capabilities that this instance consumes from communication channels.',
543
+ '',
544
+ '**Examples:**',
545
+ '- `["user.*", "order.create"]` - Specific capability patterns',
546
+ '- `["database.*"]` - All database capabilities'
547
+ ]);
548
+ }
549
+
550
+ if (word === 'capabilities') {
551
+ return new vscode.Hover([
552
+ '**Capabilities** *(Array<string>)*',
553
+ '',
554
+ 'List of capabilities available on this communication channel.',
555
+ '',
556
+ '**Used by:** Communication channel definitions to specify what operations are available for instances to advertise/use.'
557
+ ]);
558
+ }
559
+
560
+ return;
561
+ }
562
+ }
563
+
564
+ // Helper functions
565
+
566
+ function isSpecVerseDocument(document: vscode.TextDocument): boolean {
567
+ return (
568
+ document.languageId === 'specly' ||
569
+ document.fileName.endsWith('.specly')
570
+ );
571
+ }
572
+
573
+ function analyzeContext(document: vscode.TextDocument, position: vscode.Position) {
574
+ const line = document.lineAt(position).text;
575
+ const linePrefix = line.substring(0, position.character);
576
+
577
+ // Check if we're in attributes section
578
+ const isInAttributesSection = (() => {
579
+ for (let i = position.line; i >= 0; i--) {
580
+ const checkLine = document.lineAt(i).text;
581
+ if (checkLine.trim() === 'attributes:') return true;
582
+ if (checkLine.trim().endsWith(':') && !checkLine.includes(' ')) return false;
583
+ }
584
+ return false;
585
+ })();
586
+
587
+ // Check if we're in relationships section
588
+ const isInRelationshipsSection = (() => {
589
+ for (let i = position.line; i >= 0; i--) {
590
+ const checkLine = document.lineAt(i).text;
591
+ if (checkLine.trim() === 'relationships:') return true;
592
+ if (checkLine.trim().endsWith(':') && !checkLine.includes(' ')) return false;
593
+ }
594
+ return false;
595
+ })();
596
+
597
+ // Check if we're in deployment instances section
598
+ const isInDeploymentSection = (() => {
599
+ for (let i = position.line; i >= 0; i--) {
600
+ const checkLine = document.lineAt(i).text;
601
+ if (checkLine.trim() === 'instances:' || checkLine.trim() === 'communications:') return true;
602
+ if (checkLine.trim().endsWith(':') && !checkLine.includes(' ')) return false;
603
+ }
604
+ return false;
605
+ })();
606
+
607
+ return {
608
+ isAttributeType: isInAttributesSection && linePrefix.match(/^\s*\w+:\s*$/),
609
+ isModifier: isInAttributesSection && linePrefix.match(/^\s*\w+:\s*\w+\s+$/),
610
+ isRelationshipType: isInRelationshipsSection && linePrefix.match(/^\s*\w+:\s*$/),
611
+ isTopLevel: !linePrefix.includes(' ') && linePrefix.trim().endsWith(':'),
612
+ isDeploymentProperty: isInDeploymentSection && linePrefix.match(/^\s+\w+:\s*$/)
613
+ };
614
+ }
615
+
616
+ function getTypeDocumentation(type: string): string {
617
+ const docs: { [key: string]: string } = {
618
+ 'String': 'Variable-length text field (default max 255 characters)',
619
+ 'Text': 'Long text field for large content',
620
+ 'Integer': 'Whole number',
621
+ 'Number': 'Decimal number',
622
+ 'Boolean': 'True/false value',
623
+ 'Date': 'Date without time',
624
+ 'DateTime': 'Date and time timestamp',
625
+ 'UUID': 'Universally Unique Identifier',
626
+ 'Email': 'Email address with validation',
627
+ 'URL': 'Web URL with validation',
628
+ 'JSON': 'JSON object or array',
629
+ 'Object': 'Structured object',
630
+ 'Array': 'List of values'
631
+ };
632
+
633
+ return docs[type] || 'SpecVerse data type';
634
+ }
635
+
636
+ async function validateDocument(document: vscode.TextDocument, diagnostics: vscode.DiagnosticCollection) {
637
+ try {
638
+ diagnostics.clear();
639
+
640
+ const config = vscode.workspace.getConfiguration('specverse');
641
+ const cliPath = config.get('cli.path') || 'specverse';
642
+
643
+ const workingDir = dirname(document.fileName);
644
+ const { stdout, stderr } = await execAsync(`"${cliPath}" validate "${document.fileName}"`, { cwd: workingDir });
645
+
646
+ // Success - clear any existing diagnostics
647
+ if (stdout.includes('✅') && !stderr) {
648
+ return;
649
+ }
650
+
651
+ // Parse validation errors from both stdout and stderr
652
+ const errors: vscode.Diagnostic[] = [];
653
+ const allOutput = (stdout + '\n' + stderr).split('\n');
654
+
655
+ allOutput.forEach((line) => {
656
+ line = line.trim();
657
+ if (!line) return;
658
+
659
+ // Parse different error patterns
660
+ let errorMessage = '';
661
+ let severity = vscode.DiagnosticSeverity.Error;
662
+ let lineNumber = 0;
663
+
664
+ // Pattern 1: Numbered validation errors from CLI (e.g., " 1. /components/Test: Unknown property")
665
+ const numberedErrorMatch = line.match(/^\d+\.\s*(.+)$/);
666
+ if (numberedErrorMatch) {
667
+ errorMessage = numberedErrorMatch[1].trim();
668
+ }
669
+ // Pattern 2: ❌ Error messages
670
+ else if (line.includes('❌') && !line.includes('Validation failed')) {
671
+ errorMessage = line.replace(/❌/g, '').trim();
672
+ }
673
+ // Pattern 3: Error: prefix
674
+ else if (line.includes('Error:')) {
675
+ errorMessage = line.replace(/Error:/, '').trim();
676
+ }
677
+ // Pattern 4: Warning messages
678
+ else if (line.includes('⚠️') || line.includes('Warning:')) {
679
+ errorMessage = line.replace(/⚠️|Warning:/, '').trim();
680
+ severity = vscode.DiagnosticSeverity.Warning;
681
+ }
682
+ // Pattern 5: Schema validation errors (often contain "at line X")
683
+ else if (line.includes('at line') || line.includes('line:')) {
684
+ const lineMatch = line.match(/(?:at line|line:?\s*)(\d+)/i);
685
+ if (lineMatch) {
686
+ lineNumber = Math.max(0, parseInt(lineMatch[1]) - 1); // Convert to 0-based
687
+ }
688
+ errorMessage = line;
689
+ }
690
+ // Pattern 6: JSON Schema errors
691
+ else if (line.includes('should') && (line.includes('property') || line.includes('type') || line.includes('required'))) {
692
+ errorMessage = line;
693
+ severity = vscode.DiagnosticSeverity.Error;
694
+ }
695
+ // Pattern 7: Parser errors
696
+ else if (line.includes('Parse error') || line.includes('Syntax error')) {
697
+ errorMessage = line;
698
+ }
699
+ // Skip validation header lines (don't create diagnostics for these)
700
+ else if (line.includes('Validation failed') || line.includes('Validation Errors:') || line.includes('📝')) {
701
+ return; // Skip these header lines
702
+ }
703
+
704
+ if (errorMessage) {
705
+ const diagnostic = new vscode.Diagnostic(
706
+ new vscode.Range(lineNumber, 0, lineNumber, Number.MAX_SAFE_INTEGER),
707
+ errorMessage,
708
+ severity
709
+ );
710
+ diagnostic.source = 'SpecVerse';
711
+ errors.push(diagnostic);
712
+ }
713
+ });
714
+
715
+ // If we found errors, set them
716
+ if (errors.length > 0) {
717
+ diagnostics.set(document.uri, errors);
718
+ } else if (!stdout.includes('✅')) {
719
+ // CLI ran but no clear success message and no parseable errors
720
+ const diagnostic = new vscode.Diagnostic(
721
+ new vscode.Range(0, 0, 0, 0),
722
+ 'SpecVerse validation completed with unknown status. Check output for details.',
723
+ vscode.DiagnosticSeverity.Information
724
+ );
725
+ diagnostic.source = 'SpecVerse';
726
+ diagnostics.set(document.uri, [diagnostic]);
727
+ }
728
+
729
+ } catch (error: any) {
730
+ // CLI execution error - parse stdout for validation errors
731
+ if (error.code === 'ENOENT') {
732
+ const diagnostic = new vscode.Diagnostic(
733
+ new vscode.Range(0, 0, 0, 0),
734
+ 'SpecVerse CLI not found. Please configure cli.path in settings or ensure specverse is on PATH',
735
+ vscode.DiagnosticSeverity.Error
736
+ );
737
+ diagnostic.source = 'SpecVerse';
738
+ diagnostics.set(document.uri, [diagnostic]);
739
+ return;
740
+ }
741
+
742
+ // Parse validation errors from stdout when command fails (CLI outputs errors to stdout)
743
+ if (error.stdout) {
744
+ const errors: vscode.Diagnostic[] = [];
745
+ const errorLines = error.stdout.split('\n');
746
+
747
+ errorLines.forEach((line) => {
748
+ line = line.trim();
749
+ if (!line) return;
750
+
751
+ let errorMessage = '';
752
+ let severity = vscode.DiagnosticSeverity.Error;
753
+ let lineNumber = 0;
754
+
755
+ // Pattern 1: Numbered validation errors from CLI (e.g., " 1. /components/Test: Unknown property")
756
+ const numberedErrorMatch = line.match(/^\d+\.\s*(.+)$/);
757
+ if (numberedErrorMatch) {
758
+ errorMessage = numberedErrorMatch[1].trim();
759
+ }
760
+ // Pattern 2: ❌ Error messages from CLI
761
+ else if (line.includes('❌') && !line.includes('Validation failed')) {
762
+ errorMessage = line.replace(/❌/g, '').trim();
763
+ }
764
+ // Pattern 3: Direct error descriptions (like "Unknown property 'webservice'")
765
+ else if (line.includes('Unknown property') || line.includes('should') || line.includes('required')) {
766
+ errorMessage = line;
767
+ }
768
+ // Pattern 4: Path-based errors (like "/deployments/TestDeployment/instances:")
769
+ else if (line.includes('/') && line.includes(':')) {
770
+ errorMessage = line;
771
+ }
772
+ // Pattern 5: Warning messages
773
+ else if (line.includes('⚠️') || line.includes('Warning:')) {
774
+ errorMessage = line.replace(/⚠️|Warning:/, '').trim();
775
+ severity = vscode.DiagnosticSeverity.Warning;
776
+ }
777
+ // Skip validation header lines (don't create diagnostics for these)
778
+ else if (line.includes('Validation failed') || line.includes('Validation Errors:') || line.includes('📝')) {
779
+ return; // Skip these header lines
780
+ }
781
+
782
+ if (errorMessage) {
783
+ const diagnostic = new vscode.Diagnostic(
784
+ new vscode.Range(lineNumber, 0, lineNumber, Number.MAX_SAFE_INTEGER),
785
+ errorMessage,
786
+ severity
787
+ );
788
+ diagnostic.source = 'SpecVerse';
789
+ errors.push(diagnostic);
790
+ }
791
+ });
792
+
793
+ if (errors.length > 0) {
794
+ diagnostics.set(document.uri, errors);
795
+ return;
796
+ }
797
+ }
798
+
799
+ // Fallback for unknown errors
800
+ const diagnostic = new vscode.Diagnostic(
801
+ new vscode.Range(0, 0, 0, 0),
802
+ `SpecVerse CLI error: ${error.message}`,
803
+ vscode.DiagnosticSeverity.Error
804
+ );
805
+ diagnostic.source = 'SpecVerse';
806
+ diagnostics.set(document.uri, [diagnostic]);
807
+ }
808
+ }
809
+
810
+ async function formatDocument(editor: vscode.TextEditor) {
811
+ try {
812
+ const document = editor.document;
813
+ const config = vscode.workspace.getConfiguration('specverse');
814
+ const cliPath = config.get('cli.path') || 'specverse';
815
+
816
+ // Format command is not available in current CLI, show message
817
+ vscode.window.showInformationMessage('Format command is not currently available in SpecVerse CLI');
818
+ return;
819
+
820
+ if (stdout) {
821
+ const edit = new vscode.WorkspaceEdit();
822
+ const fullRange = new vscode.Range(
823
+ document.positionAt(0),
824
+ document.positionAt(document.getText().length)
825
+ );
826
+ edit.replace(document.uri, fullRange, stdout);
827
+ await vscode.workspace.applyEdit(edit);
828
+ }
829
+
830
+ } catch (error: any) {
831
+ vscode.window.showErrorMessage(`Format failed: ${error.message}`);
832
+ }
833
+ }
834
+
835
+ async function generateDiagramForDocument(document: vscode.TextDocument) {
836
+ try {
837
+ const config = vscode.workspace.getConfiguration('specverse');
838
+ const cliPath = config.get('cli.path') || 'specverse';
839
+
840
+ const diagramType = await vscode.window.showQuickPick([
841
+ 'er', 'sequence', 'architecture', 'lifecycle', 'deployment', 'all'
842
+ ], {
843
+ placeHolder: 'Select diagram type to generate'
844
+ });
845
+
846
+ if (!diagramType) return;
847
+
848
+ const workingDir = dirname(document.fileName);
849
+ const baseName = basename(document.fileName, extname(document.fileName));
850
+ const outputFile = join(workingDir, `${baseName}-${diagramType}.mmd`);
851
+
852
+ console.log(`[SpecVerse] Working directory: ${workingDir}`);
853
+ console.log(`[SpecVerse] Output file: ${outputFile}`);
854
+ console.log(`[SpecVerse] Command: "${cliPath}" gen uml "${document.fileName}" --output "${outputFile}"`);
855
+
856
+ await execAsync(`"${cliPath}" gen uml "${document.fileName}" --output "${outputFile}"`, { cwd: workingDir });
857
+ vscode.window.showInformationMessage(`${diagramType} diagram generated successfully`);
858
+
859
+ } catch (error: any) {
860
+ vscode.window.showErrorMessage(`Diagram generation failed: ${error.message}`);
861
+ }
862
+ }
863
+
864
+ async function generateDocsForDocument(document: vscode.TextDocument) {
865
+ try {
866
+ const config = vscode.workspace.getConfiguration('specverse');
867
+ const cliPath = config.get('cli.path') || 'specverse';
868
+
869
+ const format = await vscode.window.showQuickPick([
870
+ 'markdown', 'html', 'openapi'
871
+ ], {
872
+ placeHolder: 'Select documentation format'
873
+ });
874
+
875
+ if (!format) return;
876
+
877
+ const workingDir = dirname(document.fileName);
878
+ await execAsync(`"${cliPath}" gen docs "${document.fileName}"`, { cwd: workingDir });
879
+ vscode.window.showInformationMessage(`${format} documentation generated successfully`);
880
+
881
+ } catch (error: any) {
882
+ vscode.window.showErrorMessage(`Documentation generation failed: ${error.message}`);
883
+ }
884
+ }
885
+
886
+ async function generateAIForDocument(document: vscode.TextDocument) {
887
+ try {
888
+ const config = vscode.workspace.getConfiguration('specverse');
889
+ const cliPath = config.get('cli.path') || 'specverse';
890
+
891
+ const workingDir = dirname(document.fileName);
892
+ await execAsync(`"${cliPath}" gen views "${document.fileName}"`, { cwd: workingDir });
893
+ vscode.window.showInformationMessage('AI-optimized specification generated successfully');
894
+
895
+ } catch (error: any) {
896
+ vscode.window.showErrorMessage(`AI generation failed: ${error.message}`);
897
+ }
898
+ }
899
+
900
+ async function processSpeclyDocument(document: vscode.TextDocument) {
901
+ try {
902
+ const config = vscode.workspace.getConfiguration('specverse');
903
+ const cliPath = config.get('cli.path') || 'specverse';
904
+
905
+ const workingDir = dirname(document.fileName);
906
+ const outputFile = document.fileName.replace('.specly', '.yaml');
907
+ await execAsync(`"${cliPath}" gen yaml "${document.fileName}" --output "${outputFile}"`, { cwd: workingDir });
908
+
909
+ vscode.window.showInformationMessage(`Generated expanded YAML: ${outputFile}`);
910
+
911
+ // Ask if user wants to open the generated file
912
+ const openFile = await vscode.window.showInformationMessage(
913
+ 'Open generated .yaml file?',
914
+ 'Open',
915
+ 'Cancel'
916
+ );
917
+
918
+ if (openFile === 'Open') {
919
+ const yamlDocument = await vscode.workspace.openTextDocument(outputFile);
920
+ await vscode.window.showTextDocument(yamlDocument);
921
+ }
922
+
923
+ } catch (error: any) {
924
+ vscode.window.showErrorMessage(`Processing failed: ${error.message}`);
925
+ }
926
+ }
927
+
928
+ async function inferCompleteSystemForDocument(document: vscode.TextDocument) {
929
+ try {
930
+ const config = vscode.workspace.getConfiguration('specverse');
931
+ const cliPath = config.get('cli.path') || 'specverse';
932
+
933
+ if (!config.get('inference.enabled')) {
934
+ vscode.window.showInformationMessage('AI inference is disabled in settings');
935
+ return;
936
+ }
937
+
938
+ const outputFile = document.fileName.replace('.specly', '-inferred.specly');
939
+ await vscode.window.withProgress({
940
+ location: vscode.ProgressLocation.Notification,
941
+ title: 'Running AI inference...',
942
+ cancellable: false
943
+ }, async (progress) => {
944
+ progress.report({ message: 'Generating complete system architecture' });
945
+ const workingDir = dirname(document.fileName);
946
+ await execAsync(`node dist/inference-engine/test-cli.js "${document.fileName}" -o "${outputFile}"`, { cwd: workingDir });
947
+ });
948
+
949
+ vscode.window.showInformationMessage(`AI-inferred complete system generated: ${outputFile}`);
950
+
951
+ // Ask if user wants to open the generated file
952
+ const openFile = await vscode.window.showInformationMessage(
953
+ 'Open AI-inferred complete system?',
954
+ 'Open',
955
+ 'Cancel'
956
+ );
957
+
958
+ if (openFile === 'Open') {
959
+ const inferredDocument = await vscode.workspace.openTextDocument(outputFile);
960
+ await vscode.window.showTextDocument(inferredDocument);
961
+ }
962
+
963
+ } catch (error: any) {
964
+ vscode.window.showErrorMessage(`AI inference failed: ${error.message}`);
965
+ }
966
+ }
967
+
968
+ async function runTestCycleForDocument(document: vscode.TextDocument) {
969
+ try {
970
+ const config = vscode.workspace.getConfiguration('specverse');
971
+ const cliPath = config.get('cli.path') || 'specverse';
972
+
973
+ if (!config.get('testing.enableCycle')) {
974
+ vscode.window.showInformationMessage('Test cycle is disabled in settings');
975
+ return;
976
+ }
977
+
978
+ await vscode.window.withProgress({
979
+ location: vscode.ProgressLocation.Notification,
980
+ title: 'Running test cycle...',
981
+ cancellable: false
982
+ }, async (progress) => {
983
+ progress.report({ message: 'Validating → Processing → Validating' });
984
+ const workingDir = dirname(document.fileName);
985
+ await execAsync(`"${cliPath}" test cycle "${document.fileName}"`, { cwd: workingDir });
986
+ });
987
+
988
+ vscode.window.showInformationMessage('Test cycle completed successfully');
989
+
990
+ } catch (error: any) {
991
+ vscode.window.showErrorMessage(`Test cycle failed: ${error.message}`);
992
+ }
993
+ }
994
+
995
+ async function executeCliCommand(document: vscode.TextDocument, commandName: string) {
996
+ // Map VSCode command names to exact CLI commands
997
+ const commandMap: { [key: string]: string } = {
998
+ // Single commands (unchanged)
999
+ 'validate': 'validate',
1000
+ 'infer': 'infer',
1001
+ 'init': 'init',
1002
+ 'cache': 'cache',
1003
+ 'help': 'help',
1004
+ 'gen': 'gen',
1005
+ 'dev': 'dev',
1006
+ 'test': 'test',
1007
+
1008
+ // Grouped commands - map compressed names to CLI format
1009
+ 'genyaml': 'gen yaml',
1010
+ 'gendiagram': 'gen diagram',
1011
+ 'gendocs': 'gen docs',
1012
+ 'genviews': 'gen views',
1013
+ 'genall': 'gen all',
1014
+ 'devquick': 'dev quick',
1015
+ 'devformat': 'dev format',
1016
+ 'devwatch': 'dev watch',
1017
+ 'testcycle': 'test cycle',
1018
+ 'testbatch': 'test batch'
1019
+ };
1020
+
1021
+ const cliCommand = commandMap[commandName] || commandName;
1022
+
1023
+ try {
1024
+ const config = vscode.workspace.getConfiguration('specverse');
1025
+ const cliPath = config.get('cli.path') || 'specverse';
1026
+ const workingDir = dirname(document.fileName);
1027
+ const fullCommand = `"${cliPath}" ${cliCommand} "${document.fileName}"`;
1028
+
1029
+ console.log(`[SpecVerse] Executing: ${fullCommand}`);
1030
+
1031
+ await vscode.window.withProgress({
1032
+ location: vscode.ProgressLocation.Notification,
1033
+ title: `Running SpecVerse ${cliCommand}...`,
1034
+ cancellable: false
1035
+ }, async (progress) => {
1036
+ progress.report({ message: 'Processing specification file' });
1037
+ const { stdout, stderr } = await execAsync(fullCommand, { cwd: workingDir });
1038
+
1039
+ // Log all output for debugging
1040
+ if (stdout) console.log(`[SpecVerse] stdout:`, stdout);
1041
+ if (stderr) console.log(`[SpecVerse] stderr:`, stderr);
1042
+ });
1043
+
1044
+ vscode.window.showInformationMessage(`SpecVerse ${cliCommand} completed successfully`);
1045
+
1046
+ } catch (error: any) {
1047
+ console.log(`[SpecVerse] Command failed:`, error);
1048
+
1049
+ // Create diagnostics collection for this command if it doesn't exist
1050
+ const diagnostics = vscode.languages.createDiagnosticCollection(`specverse-${commandName}`);
1051
+
1052
+ // Parse CLI output errors (same logic as validateDocument)
1053
+ const errors: vscode.Diagnostic[] = [];
1054
+
1055
+ // Check both stdout and stderr for errors
1056
+ const allOutput = ((error.stdout || '') + '\n' + (error.stderr || '')).split('\n');
1057
+
1058
+ allOutput.forEach((line) => {
1059
+ line = line.trim();
1060
+ if (!line) return;
1061
+
1062
+ let errorMessage = '';
1063
+ let severity = vscode.DiagnosticSeverity.Error;
1064
+ let lineNumber = 0;
1065
+
1066
+ // Pattern 1: Numbered validation errors from CLI (e.g., " 1. /components/Test: Unknown property")
1067
+ const numberedErrorMatch = line.match(/^\d+\.\s*(.+)$/);
1068
+ if (numberedErrorMatch) {
1069
+ errorMessage = numberedErrorMatch[1].trim();
1070
+ }
1071
+ // Pattern 2: ❌ Error messages from CLI
1072
+ else if (line.includes('❌') && !line.includes('Validation failed')) {
1073
+ errorMessage = line.replace(/❌/g, '').trim();
1074
+ }
1075
+ // Pattern 3: Direct error descriptions
1076
+ else if (line.includes('Unknown property') || line.includes('should') || line.includes('required')) {
1077
+ errorMessage = line;
1078
+ }
1079
+ // Pattern 4: Path-based errors
1080
+ else if (line.includes('/') && line.includes(':')) {
1081
+ errorMessage = line;
1082
+ }
1083
+ // Pattern 5: Warning messages
1084
+ else if (line.includes('⚠️') || line.includes('Warning:')) {
1085
+ errorMessage = line.replace(/⚠️|Warning:/, '').trim();
1086
+ severity = vscode.DiagnosticSeverity.Warning;
1087
+ }
1088
+ // Skip validation header lines (don't create diagnostics for these)
1089
+ else if (line.includes('Validation failed') || line.includes('Validation Errors:') || line.includes('📝')) {
1090
+ return; // Skip these header lines
1091
+ }
1092
+
1093
+ if (errorMessage) {
1094
+ const diagnostic = new vscode.Diagnostic(
1095
+ new vscode.Range(lineNumber, 0, lineNumber, Number.MAX_SAFE_INTEGER),
1096
+ errorMessage,
1097
+ severity
1098
+ );
1099
+ diagnostic.source = 'SpecVerse';
1100
+ errors.push(diagnostic);
1101
+ }
1102
+ });
1103
+
1104
+ // Display errors in Problems panel
1105
+ if (errors.length > 0) {
1106
+ diagnostics.set(document.uri, errors);
1107
+ vscode.window.showErrorMessage(`SpecVerse ${cliCommand} failed with ${errors.length} errors. See Problems panel for details.`);
1108
+ } else {
1109
+ // Fallback error message
1110
+ const diagnostic = new vscode.Diagnostic(
1111
+ new vscode.Range(0, 0, 0, 0),
1112
+ `SpecVerse ${cliCommand} failed: ${error.message}`,
1113
+ vscode.DiagnosticSeverity.Error
1114
+ );
1115
+ diagnostic.source = 'SpecVerse';
1116
+ diagnostics.set(document.uri, [diagnostic]);
1117
+ vscode.window.showErrorMessage(`SpecVerse ${cliCommand} failed: ${error.message}`);
1118
+ }
1119
+ }
1120
+ }
1121
+
1122
+ async function runMigrateCommand(targetDir: string) {
1123
+ try {
1124
+ const config = vscode.workspace.getConfiguration('specverse');
1125
+ const cliPath = config.get('cli.path') || 'specverse';
1126
+
1127
+ // Ask user for confirmation and options
1128
+ const dryRun = await vscode.window.showQuickPick([
1129
+ { label: 'Migrate', description: 'Apply migration to files', value: false },
1130
+ { label: 'Dry Run', description: 'Preview changes without modifying files', value: true }
1131
+ ], {
1132
+ placeHolder: 'Choose migration mode'
1133
+ });
1134
+
1135
+ if (!dryRun) return;
1136
+
1137
+ const dryRunFlag = dryRun.value ? '--dry-run' : '';
1138
+ const fullCommand = `"${cliPath}" migrate ${dryRunFlag} "${targetDir}"`;
1139
+
1140
+ console.log(`[SpecVerse] Executing: ${fullCommand}`);
1141
+
1142
+ await vscode.window.withProgress({
1143
+ location: vscode.ProgressLocation.Notification,
1144
+ title: `Migrating specs to v3.5 format...`,
1145
+ cancellable: false
1146
+ }, async (progress) => {
1147
+ progress.report({ message: dryRun.value ? 'Previewing changes...' : 'Applying migration...' });
1148
+ const { stdout, stderr } = await execAsync(fullCommand, { cwd: targetDir });
1149
+
1150
+ // Show output in output channel
1151
+ const outputChannel = vscode.window.createOutputChannel('SpecVerse Migration');
1152
+ outputChannel.clear();
1153
+ if (stdout) outputChannel.appendLine(stdout);
1154
+ if (stderr) outputChannel.appendLine(stderr);
1155
+ outputChannel.show();
1156
+ });
1157
+
1158
+ vscode.window.showInformationMessage(
1159
+ dryRun.value
1160
+ ? 'Migration preview complete. Check output for details.'
1161
+ : 'Migration completed successfully!'
1162
+ );
1163
+
1164
+ } catch (error: any) {
1165
+ vscode.window.showErrorMessage(`Migration failed: ${error.message}`);
1166
+ }
1167
+ }
1168
+
1169
+ async function runBatchDiagramGeneration() {
1170
+ try {
1171
+ const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
1172
+ if (!workspaceFolder) {
1173
+ vscode.window.showErrorMessage('No workspace folder found');
1174
+ return;
1175
+ }
1176
+
1177
+ await vscode.window.withProgress({
1178
+ location: vscode.ProgressLocation.Notification,
1179
+ title: 'Generating batch diagrams...',
1180
+ cancellable: false
1181
+ }, async (progress) => {
1182
+ progress.report({ message: 'Processing all .specly files and generating enhanced diagrams' });
1183
+ await execAsync('node scripts/generate-diagrams-batch.js', { cwd: workspaceFolder.uri.fsPath });
1184
+ });
1185
+
1186
+ vscode.window.showInformationMessage('Batch diagram generation completed successfully');
1187
+
1188
+ } catch (error: any) {
1189
+ vscode.window.showErrorMessage(`Batch diagram generation failed: ${error.message}`);
1190
+ }
1191
+ }
1192
+
1193
+ export function deactivate() {
1194
+ console.log('SpecVerse v3.5 extension deactivated');
1195
+ }