@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.
- package/assets/examples/09-api/ai-spec.yaml +194 -0
- package/assets/examples/09-api/converted.yaml +95 -0
- package/assets/examples/09-api/diagram-architecture.mmd +10 -0
- package/assets/examples/09-api/diagram-er.mmd +10 -0
- package/assets/examples/09-api/documentation.html +104 -0
- package/assets/examples/09-api/documentation.md +95 -0
- package/assets/examples/09-api/inferred-spec.yaml +420 -0
- package/assets/examples/09-api/openapi.json +61 -0
- package/assets/examples/10-api/README.md +216 -0
- package/assets/examples/10-api/ai-spec.yaml +194 -0
- package/assets/examples/10-api/converted.yaml +96 -0
- package/assets/examples/10-api/diagram-architecture.mmd +10 -0
- package/assets/examples/10-api/diagram-er.mmd +10 -0
- package/assets/examples/10-api/documentation.html +104 -0
- package/assets/examples/10-api/documentation.md +95 -0
- package/assets/examples/10-api/inferred-spec.yaml +7 -0
- package/assets/examples/10-api/metadata.yaml +89 -0
- package/assets/examples/10-api/openapi.json +61 -0
- package/assets/examples/10-api/package-integration-test.js +177 -0
- package/assets/examples/10-api/usage-example.js +323 -0
- package/assets/examples/10-api/usage-example.ts +363 -0
- package/assets/examples/10-api/workflow-test.js +113 -0
- package/assets/examples/manifests/01-simple-default-mappings.yaml +36 -0
- package/assets/examples/manifests/02-capability-mappings.yaml +55 -0
- package/assets/examples/manifests/03-hybrid-mappings.yaml +109 -0
- package/assets/examples/manifests/README.md +245 -0
- package/assets/examples/manifests/backend-only.yaml +43 -0
- package/assets/examples/manifests/blog-api.md +78 -0
- package/assets/examples/manifests/blog-api.specly +79 -0
- package/assets/examples/manifests/frontend-only.yaml +27 -0
- package/assets/examples/manifests/fullstack-app.yaml +44 -0
- package/assets/examples/manifests/fullstack-monorepo.yaml +62 -0
- package/assets/examples/validate-examples-with-expected-failures.cjs +328 -0
- package/assets/examples/validate-examples.cjs +225 -0
- package/assets/examples-decomposed/cloud-native-manifest.example.yaml +8 -0
- package/assets/examples-decomposed/cloud-native-manifest.md +379 -0
- package/assets/examples-decomposed/cloud-native-manifest.specly +60 -0
- package/assets/examples-decomposed/docker-compose-manifest.example.yaml +8 -0
- package/assets/examples-decomposed/docker-compose-manifest.md +326 -0
- package/assets/examples-decomposed/docker-compose-manifest.specly +40 -0
- package/assets/examples-decomposed/kubernetes-deployment-manifest.example.yaml +8 -0
- package/assets/examples-decomposed/kubernetes-deployment-manifest.md +237 -0
- package/assets/examples-decomposed/kubernetes-deployment-manifest.specly +41 -0
- package/assets/templates/README.md +559 -0
- package/assets/templates/TEMPLATE-ENHANCEMENTS-V33.md +462 -0
- package/assets/templates/backend-only/CLAUDE.md +73 -0
- package/assets/templates/backend-only/README.md +197 -0
- package/assets/templates/backend-only/deployments/README.md +149 -0
- package/assets/templates/backend-only/deployments/development.specly +53 -0
- package/assets/templates/backend-only/deployments/production.specly +87 -0
- package/assets/templates/backend-only/docs/README.md +50 -0
- package/assets/templates/backend-only/docs/api/README.md +7 -0
- package/assets/templates/backend-only/docs/diagrams/README.md +85 -0
- package/assets/templates/backend-only/docs/example-documentation-template.md +269 -0
- package/assets/templates/backend-only/docs/guides/README.md +15 -0
- package/assets/templates/backend-only/dot.env.example +18 -0
- package/assets/templates/backend-only/generated/README.md +56 -0
- package/assets/templates/backend-only/generated/code/integration-test.template.js +320 -0
- package/assets/templates/backend-only/generated/code/package.json.template +34 -0
- package/assets/templates/backend-only/generated/docs/README.md +49 -0
- package/assets/templates/backend-only/gitignore +54 -0
- package/assets/templates/backend-only/manifests/README.md +72 -0
- package/assets/templates/backend-only/manifests/docker-compose.specly +91 -0
- package/assets/templates/backend-only/manifests/implementation.yaml +100 -0
- package/assets/templates/backend-only/manifests/kubernetes.specly +140 -0
- package/assets/templates/backend-only/package.json +59 -0
- package/assets/templates/backend-only/scripts/test-all.sh +160 -0
- package/assets/templates/backend-only/scripts/test-generated-code.sh +165 -0
- package/assets/templates/backend-only/specs/main.specly +67 -0
- package/assets/templates/default/CLAUDE.md +141 -0
- package/assets/templates/default/README.md +404 -0
- package/assets/templates/default/deployments/README.md +149 -0
- package/assets/templates/default/deployments/development.specly +53 -0
- package/assets/templates/default/deployments/production.specly +87 -0
- package/assets/templates/default/docs/README.md +50 -0
- package/assets/templates/default/docs/api/README.md +7 -0
- package/assets/templates/default/docs/diagrams/README.md +85 -0
- package/assets/templates/default/docs/example-documentation-template.md +269 -0
- package/assets/templates/default/docs/guides/README.md +15 -0
- package/assets/templates/default/dot.env.example +18 -0
- package/assets/templates/default/generated/README.md +56 -0
- package/assets/templates/default/generated/code/integration-test.template.js +320 -0
- package/assets/templates/default/generated/code/package.json.template +34 -0
- package/assets/templates/default/generated/docs/README.md +49 -0
- package/assets/templates/default/gitignore +54 -0
- package/assets/templates/default/manifests/README.md +72 -0
- package/assets/templates/default/manifests/docker-compose.specly +91 -0
- package/assets/templates/default/manifests/implementation.yaml +176 -0
- package/assets/templates/default/manifests/kubernetes.specly +140 -0
- package/assets/templates/default/package.json +61 -0
- package/assets/templates/default/scripts/test-all.sh +160 -0
- package/assets/templates/default/scripts/test-generated-code.sh +165 -0
- package/assets/templates/default/specs/main.specly +67 -0
- package/assets/templates/frontend-only/CLAUDE.md +75 -0
- package/assets/templates/frontend-only/README.md +231 -0
- package/assets/templates/frontend-only/deployments/README.md +149 -0
- package/assets/templates/frontend-only/deployments/development.specly +53 -0
- package/assets/templates/frontend-only/deployments/production.specly +87 -0
- package/assets/templates/frontend-only/docs/README.md +50 -0
- package/assets/templates/frontend-only/docs/api/README.md +7 -0
- package/assets/templates/frontend-only/docs/diagrams/README.md +85 -0
- package/assets/templates/frontend-only/docs/example-documentation-template.md +269 -0
- package/assets/templates/frontend-only/docs/guides/README.md +15 -0
- package/assets/templates/frontend-only/dot.env.example +18 -0
- package/assets/templates/frontend-only/generated/README.md +56 -0
- package/assets/templates/frontend-only/generated/code/integration-test.template.js +320 -0
- package/assets/templates/frontend-only/generated/code/package.json.template +34 -0
- package/assets/templates/frontend-only/generated/docs/README.md +49 -0
- package/assets/templates/frontend-only/gitignore +54 -0
- package/assets/templates/frontend-only/manifests/README.md +72 -0
- package/assets/templates/frontend-only/manifests/docker-compose.specly +91 -0
- package/assets/templates/frontend-only/manifests/implementation.yaml +58 -0
- package/assets/templates/frontend-only/manifests/kubernetes.specly +140 -0
- package/assets/templates/frontend-only/package.json +59 -0
- package/assets/templates/frontend-only/scripts/test-all.sh +160 -0
- package/assets/templates/frontend-only/scripts/test-generated-code.sh +165 -0
- package/assets/templates/frontend-only/specs/main.specly +57 -0
- package/assets/templates/full-stack/AI-GUIDE.md +60 -0
- package/assets/templates/full-stack/CLAUDE.md +141 -0
- package/assets/templates/full-stack/README.md +382 -0
- package/assets/templates/full-stack/archive/AI-GUIDE-legacy.md +392 -0
- package/assets/templates/full-stack/deployments/README.md +149 -0
- package/assets/templates/full-stack/deployments/development.specly +53 -0
- package/assets/templates/full-stack/deployments/production.specly +87 -0
- package/assets/templates/full-stack/docs/README.md +51 -0
- package/assets/templates/full-stack/docs/api/README.md +7 -0
- package/assets/templates/full-stack/docs/diagrams/README.md +85 -0
- package/assets/templates/full-stack/docs/example-documentation-template.md +269 -0
- package/assets/templates/full-stack/docs/guides/README.md +15 -0
- package/assets/templates/full-stack/generated/README.md +56 -0
- package/assets/templates/full-stack/generated/code/integration-test.template.js +320 -0
- package/assets/templates/full-stack/generated/code/package.json.template +34 -0
- package/assets/templates/full-stack/generated/docs/README.md +49 -0
- package/assets/templates/full-stack/gitignore +54 -0
- package/assets/templates/full-stack/manifests/README.md +72 -0
- package/assets/templates/full-stack/manifests/docker-compose.specly +91 -0
- package/assets/templates/full-stack/manifests/implementation.yaml +155 -0
- package/assets/templates/full-stack/manifests/kubernetes.specly +140 -0
- package/assets/templates/full-stack/package.json +45 -0
- package/assets/templates/full-stack/scripts/test-all.sh +160 -0
- package/assets/templates/full-stack/scripts/test-generated-code.sh +165 -0
- package/assets/templates/full-stack/specs/example-v33.specly +297 -0
- package/assets/templates/full-stack/specs/main-simple.specly +73 -0
- package/assets/templates/full-stack/specs/main.specly +408 -0
- package/dist/engines/code-generator.d.ts +86 -0
- package/dist/engines/code-generator.d.ts.map +1 -0
- package/dist/engines/code-generator.js +159 -0
- package/dist/engines/code-generator.js.map +1 -0
- package/dist/engines/engine-registry.d.ts +94 -0
- package/dist/engines/engine-registry.d.ts.map +1 -0
- package/dist/engines/engine-registry.js +163 -0
- package/dist/engines/engine-registry.js.map +1 -0
- package/dist/engines/index.d.ts +10 -0
- package/dist/engines/index.d.ts.map +1 -0
- package/dist/engines/index.js +12 -0
- package/dist/engines/index.js.map +1 -0
- package/dist/engines/typescript-engine.d.ts +74 -0
- package/dist/engines/typescript-engine.d.ts.map +1 -0
- package/dist/engines/typescript-engine.js +288 -0
- package/dist/engines/typescript-engine.js.map +1 -0
- package/dist/generators/index.d.ts +11 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/index.js +11 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +434 -0
- package/dist/index.js.map +1 -0
- package/dist/library/index.d.ts +12 -0
- package/dist/library/index.d.ts.map +1 -0
- package/dist/library/index.js +15 -0
- package/dist/library/index.js.map +1 -0
- package/dist/library/library.d.ts +132 -0
- package/dist/library/library.d.ts.map +1 -0
- package/dist/library/library.js +343 -0
- package/dist/library/library.js.map +1 -0
- package/dist/library/loader.d.ts +73 -0
- package/dist/library/loader.d.ts.map +1 -0
- package/dist/library/loader.js +150 -0
- package/dist/library/loader.js.map +1 -0
- package/dist/library/resolver.d.ts +104 -0
- package/dist/library/resolver.d.ts.map +1 -0
- package/dist/library/resolver.js +299 -0
- package/dist/library/resolver.js.map +1 -0
- package/dist/library/validator.d.ts +65 -0
- package/dist/library/validator.d.ts.map +1 -0
- package/dist/library/validator.js +203 -0
- package/dist/library/validator.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/instance-factory.d.ts +289 -0
- package/dist/types/instance-factory.d.ts.map +1 -0
- package/dist/types/instance-factory.js +8 -0
- package/dist/types/instance-factory.js.map +1 -0
- package/dist/types/unified-mappings.d.ts +163 -0
- package/dist/types/unified-mappings.d.ts.map +1 -0
- package/dist/types/unified-mappings.js +110 -0
- package/dist/types/unified-mappings.js.map +1 -0
- package/dist/utils/ai-spec-loader.d.ts +77 -0
- package/dist/utils/ai-spec-loader.d.ts.map +1 -0
- package/dist/utils/ai-spec-loader.js +138 -0
- package/dist/utils/ai-spec-loader.js.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/manifest-loader.d.ts +107 -0
- package/dist/utils/manifest-loader.d.ts.map +1 -0
- package/dist/utils/manifest-loader.js +168 -0
- package/dist/utils/manifest-loader.js.map +1 -0
- package/dist/utils/mapping-migration.d.ts +53 -0
- package/dist/utils/mapping-migration.d.ts.map +1 -0
- package/dist/utils/mapping-migration.js +194 -0
- package/dist/utils/mapping-migration.js.map +1 -0
- package/libs/instance-factories/CURVED-INTERFACE.md +278 -0
- package/libs/instance-factories/README.md +433 -0
- package/libs/instance-factories/applications/generic-app.yaml +52 -0
- package/libs/instance-factories/applications/react-app.yaml +186 -0
- package/libs/instance-factories/applications/templates/generic/backend-env-generator.ts +31 -0
- package/libs/instance-factories/applications/templates/generic/backend-package-json-generator.ts +80 -0
- package/libs/instance-factories/applications/templates/generic/backend-tsconfig-generator.ts +69 -0
- package/libs/instance-factories/applications/templates/generic/main-generator.ts +308 -0
- package/libs/instance-factories/applications/templates/react/_view-components-source.ts +555 -0
- package/libs/instance-factories/applications/templates/react/api-client-generator.ts +436 -0
- package/libs/instance-factories/applications/templates/react/api-types-generator.ts +153 -0
- package/libs/instance-factories/applications/templates/react/app-tsx-generator.ts +94 -0
- package/libs/instance-factories/applications/templates/react/env-example-generator.ts +24 -0
- package/libs/instance-factories/applications/templates/react/field-helpers-generator.ts +106 -0
- package/libs/instance-factories/applications/templates/react/gitignore-generator.ts +38 -0
- package/libs/instance-factories/applications/templates/react/index-css-generator.ts +85 -0
- package/libs/instance-factories/applications/templates/react/index-html-generator.ts +30 -0
- package/libs/instance-factories/applications/templates/react/main-tsx-generator.ts +34 -0
- package/libs/instance-factories/applications/templates/react/package-json-generator.ts +54 -0
- package/libs/instance-factories/applications/templates/react/pattern-adapter-generator.ts +179 -0
- package/libs/instance-factories/applications/templates/react/react-pattern-adapter.tsx +1347 -0
- package/libs/instance-factories/applications/templates/react/relationship-field-generator.ts +150 -0
- package/libs/instance-factories/applications/templates/react/tailwind-adapter-generator.ts +704 -0
- package/libs/instance-factories/applications/templates/react/tailwind-adapter-wrapper-generator.ts +84 -0
- package/libs/instance-factories/applications/templates/react/tsconfig-generator.ts +35 -0
- package/libs/instance-factories/applications/templates/react/use-api-hooks-generator.ts +121 -0
- package/libs/instance-factories/applications/templates/react/view-dashboard-generator.ts +150 -0
- package/libs/instance-factories/applications/templates/react/view-detail-generator.ts +150 -0
- package/libs/instance-factories/applications/templates/react/view-form-generator.ts +362 -0
- package/libs/instance-factories/applications/templates/react/view-list-generator.ts +98 -0
- package/libs/instance-factories/applications/templates/react/view-router-generator.ts +89 -0
- package/libs/instance-factories/applications/templates/react/vite-config-generator.ts +49 -0
- package/libs/instance-factories/archived/fastify-prisma.yaml +104 -0
- package/libs/instance-factories/cli/commander-js.yaml +55 -0
- package/libs/instance-factories/cli/templates/commander/cli-entry-generator.d.ts +12 -0
- package/libs/instance-factories/cli/templates/commander/cli-entry-generator.d.ts.map +1 -0
- package/libs/instance-factories/cli/templates/commander/cli-entry-generator.js +115 -0
- package/libs/instance-factories/cli/templates/commander/cli-entry-generator.js.map +1 -0
- package/libs/instance-factories/cli/templates/commander/cli-entry-generator.ts +145 -0
- package/libs/instance-factories/cli/templates/commander/command-generator.d.ts +14 -0
- package/libs/instance-factories/cli/templates/commander/command-generator.d.ts.map +1 -0
- package/libs/instance-factories/cli/templates/commander/command-generator.js +182 -0
- package/libs/instance-factories/cli/templates/commander/command-generator.js.map +1 -0
- package/libs/instance-factories/cli/templates/commander/command-generator.ts +992 -0
- package/libs/instance-factories/communication/event-emitter.yaml +56 -0
- package/libs/instance-factories/communication/rabbitmq-events.yaml +87 -0
- package/libs/instance-factories/communication/templates/eventemitter/bus-generator.ts +93 -0
- package/libs/instance-factories/communication/templates/eventemitter/publisher-generator.ts +117 -0
- package/libs/instance-factories/communication/templates/eventemitter/subscriber-generator.ts +101 -0
- package/libs/instance-factories/controllers/fastify.yaml +127 -0
- package/libs/instance-factories/controllers/templates/fastify/meta-routes-generator.ts +103 -0
- package/libs/instance-factories/controllers/templates/fastify/routes-generator.ts +389 -0
- package/libs/instance-factories/controllers/templates/fastify/server-generator.ts +76 -0
- package/libs/instance-factories/infrastructure/docker-k8s.yaml +61 -0
- package/libs/instance-factories/infrastructure/templates/docker-k8s/infrastructure-generator.ts +46 -0
- package/libs/instance-factories/orms/prisma.yaml +89 -0
- package/libs/instance-factories/orms/templates/prisma/schema-generator.ts +563 -0
- package/libs/instance-factories/orms/templates/prisma/services-generator.ts +408 -0
- package/libs/instance-factories/scaffolding/generic-scaffold.yaml +65 -0
- package/libs/instance-factories/scaffolding/templates/generic/env-example-generator.ts +73 -0
- package/libs/instance-factories/scaffolding/templates/generic/env-generator.ts +85 -0
- package/libs/instance-factories/scaffolding/templates/generic/gitignore-generator.ts +69 -0
- package/libs/instance-factories/scaffolding/templates/generic/package-json-generator.ts +176 -0
- package/libs/instance-factories/scaffolding/templates/generic/readme-generator.ts +207 -0
- package/libs/instance-factories/scaffolding/templates/generic/tsconfig-generator.ts +78 -0
- package/libs/instance-factories/scaffolding/templates/generic/tsconfig-react-generator.ts +41 -0
- package/libs/instance-factories/sdks/python-sdk.yaml +66 -0
- package/libs/instance-factories/sdks/templates/python/sdk-generator.ts +50 -0
- package/libs/instance-factories/sdks/templates/typescript/sdk-generator.ts +49 -0
- package/libs/instance-factories/sdks/typescript-sdk.yaml +59 -0
- package/libs/instance-factories/services/prisma-services.yaml +71 -0
- package/libs/instance-factories/services/templates/prisma/behavior-generator.ts +303 -0
- package/libs/instance-factories/services/templates/prisma/controller-generator.ts +532 -0
- package/libs/instance-factories/services/templates/prisma/service-generator.ts +315 -0
- package/libs/instance-factories/shared/path-resolver.ts +111 -0
- package/libs/instance-factories/storage/mongodb.yaml +79 -0
- package/libs/instance-factories/storage/postgresql.yaml +75 -0
- package/libs/instance-factories/storage/redis.yaml +79 -0
- package/libs/instance-factories/storage/templates/mongodb/config-generator.ts +15 -0
- package/libs/instance-factories/storage/templates/mongodb/docker-generator.ts +18 -0
- package/libs/instance-factories/storage/templates/postgresql/config-generator.ts +54 -0
- package/libs/instance-factories/storage/templates/postgresql/docker-generator.ts +55 -0
- package/libs/instance-factories/storage/templates/redis/config-generator.ts +16 -0
- package/libs/instance-factories/storage/templates/redis/docker-generator.ts +18 -0
- package/libs/instance-factories/test-generation.ts +192 -0
- package/libs/instance-factories/testing/templates/vitest/tests-generator.ts +51 -0
- package/libs/instance-factories/testing/vitest-tests.yaml +63 -0
- package/libs/instance-factories/tools/templates/mcp/mcp-server-generator.ts +136 -0
- package/libs/instance-factories/tools/templates/mcp/static/docs/DEPLOYMENT_GUIDE.md +630 -0
- package/libs/instance-factories/tools/templates/mcp/static/docs/HYBRID_RESOURCE_SYSTEM.md +330 -0
- package/libs/instance-factories/tools/templates/mcp/static/docs/deployments/EXTENSION_DEPLOYMENT.md +552 -0
- package/libs/instance-factories/tools/templates/mcp/static/docs/deployments/LOCAL_DEPLOYMENT.md +164 -0
- package/libs/instance-factories/tools/templates/mcp/static/docs/deployments/WEB_DEPLOYMENT.md +247 -0
- package/libs/instance-factories/tools/templates/mcp/static/package.json +92 -0
- package/libs/instance-factories/tools/templates/mcp/static/scripts/build-enterprise.js +284 -0
- package/libs/instance-factories/tools/templates/mcp/static/scripts/build-extension.js +139 -0
- package/libs/instance-factories/tools/templates/mcp/static/scripts/build-local.js +74 -0
- package/libs/instance-factories/tools/templates/mcp/static/scripts/build-web.js +156 -0
- package/libs/instance-factories/tools/templates/mcp/static/scripts/copy-canonical-files.js +41 -0
- package/libs/instance-factories/tools/templates/mcp/static/scripts/test-deployments.js +259 -0
- package/libs/instance-factories/tools/templates/mcp/static/scripts/test-hybrid-resources.js +231 -0
- package/libs/instance-factories/tools/templates/mcp/static/scripts/test-hybrid-simple.js +196 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/controllers/MCPServerController.ts +293 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/events/EventEmitter.ts +90 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/index.ts +24 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/interfaces/ResourceProvider.ts +15 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/models/LibrarySuggestion.ts +106 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/models/SpecVerseResource.ts +75 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/server/mcp-server.ts +239 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/services/CLIProxyService.ts +1501 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/services/EmbeddedResourcesAdapter.ts +211 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/services/EntityModuleService.ts +308 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/services/HybridResourcesProvider.ts +210 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/services/LibraryToolsService.ts +356 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/services/OrchestratorBridge.ts +524 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/services/OrchestratorToolsService.ts +530 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/services/PromptToolsService.ts +594 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/services/ResourcesProviderService.ts +170 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/tests/unit/CLIProxyService.init.test.ts +544 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/tests/unit/CLIProxyService.test.ts +189 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/tests/unit/ResourcesProviderService.test.ts +89 -0
- package/libs/instance-factories/tools/templates/mcp/static/src/types/index.ts +110 -0
- package/libs/instance-factories/tools/templates/mcp/static/tsconfig.json +28 -0
- package/libs/instance-factories/tools/templates/vscode/static/extension.ts +1195 -0
- package/libs/instance-factories/tools/templates/vscode/static/language-configuration.json +34 -0
- package/libs/instance-factories/tools/templates/vscode/static/schemas/specverse-v3-schema.json +4279 -0
- package/libs/instance-factories/tools/templates/vscode/static/syntaxes/specverse.tmLanguage.json +138 -0
- package/libs/instance-factories/tools/templates/vscode/static/themes/README.md +74 -0
- package/libs/instance-factories/tools/templates/vscode/static/themes/complete-specverse-colors.json +122 -0
- package/libs/instance-factories/tools/templates/vscode/static/themes/specverse-basic-theme.json +65 -0
- package/libs/instance-factories/tools/templates/vscode/static/themes/specverse-complete-theme.json +123 -0
- package/libs/instance-factories/tools/templates/vscode/static/themes/specverse-theme-colors.json +64 -0
- package/libs/instance-factories/tools/templates/vscode/vscode-extension-generator.ts +214 -0
- package/libs/instance-factories/validation/templates/zod/validation-generator.ts +46 -0
- package/libs/instance-factories/validation/zod.yaml +56 -0
- package/libs/instance-factories/views/index.d.ts +13 -0
- package/libs/instance-factories/views/index.d.ts.map +1 -0
- package/libs/instance-factories/views/index.js +18 -0
- package/libs/instance-factories/views/index.js.map +1 -0
- package/libs/instance-factories/views/index.ts +45 -0
- package/libs/instance-factories/views/react-components.yaml +129 -0
- package/libs/instance-factories/views/templates/ARCHITECTURE.md +198 -0
- package/libs/instance-factories/views/templates/react/adapters/antd-adapter.ts +869 -0
- package/libs/instance-factories/views/templates/react/adapters/mui-adapter.ts +953 -0
- package/libs/instance-factories/views/templates/react/adapters/shadcn-adapter.ts +806 -0
- package/libs/instance-factories/views/templates/react/app-generator.ts +55 -0
- package/libs/instance-factories/views/templates/react/components-generator.ts +391 -0
- package/libs/instance-factories/views/templates/react/forms-generator.ts +343 -0
- package/libs/instance-factories/views/templates/react/frontend-package-json-generator.ts +54 -0
- package/libs/instance-factories/views/templates/react/hooks-generator.ts +122 -0
- package/libs/instance-factories/views/templates/react/index-css-generator.ts +209 -0
- package/libs/instance-factories/views/templates/react/index-html-generator.ts +34 -0
- package/libs/instance-factories/views/templates/react/main-tsx-generator.ts +29 -0
- package/libs/instance-factories/views/templates/react/react-component-generator.d.ts +152 -0
- package/libs/instance-factories/views/templates/react/react-component-generator.d.ts.map +1 -0
- package/libs/instance-factories/views/templates/react/react-component-generator.js +398 -0
- package/libs/instance-factories/views/templates/react/react-component-generator.js.map +1 -0
- package/libs/instance-factories/views/templates/react/react-component-generator.ts +533 -0
- package/libs/instance-factories/views/templates/react/router-generator.ts +197 -0
- package/libs/instance-factories/views/templates/react/router-generic-generator.ts +103 -0
- package/libs/instance-factories/views/templates/react/spec-json-generator.ts +17 -0
- package/libs/instance-factories/views/templates/react/types-generator.ts +76 -0
- package/libs/instance-factories/views/templates/react/views-metadata-generator.ts +42 -0
- package/libs/instance-factories/views/templates/react/vite-config-generator.ts +38 -0
- package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.d.ts.map +1 -0
- package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.js.map +1 -0
- package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.ts +474 -0
- package/libs/instance-factories/views/templates/shared/__tests__/composite-patterns.test.ts +242 -0
- package/libs/instance-factories/views/templates/shared/adapter-types.d.ts +77 -0
- package/libs/instance-factories/views/templates/shared/adapter-types.d.ts.map +1 -0
- package/libs/instance-factories/views/templates/shared/adapter-types.js +47 -0
- package/libs/instance-factories/views/templates/shared/adapter-types.js.map +1 -0
- package/libs/instance-factories/views/templates/shared/adapter-types.ts +142 -0
- package/libs/instance-factories/views/templates/shared/atomic-components-registry.d.ts +63 -0
- package/libs/instance-factories/views/templates/shared/atomic-components-registry.d.ts.map +1 -0
- package/libs/instance-factories/views/templates/shared/atomic-components-registry.js +822 -0
- package/libs/instance-factories/views/templates/shared/atomic-components-registry.js.map +1 -0
- package/libs/instance-factories/views/templates/shared/atomic-components-registry.ts +908 -0
- package/libs/instance-factories/views/templates/shared/base-generator.d.ts +247 -0
- package/libs/instance-factories/views/templates/shared/base-generator.d.ts.map +1 -0
- package/libs/instance-factories/views/templates/shared/base-generator.js +363 -0
- package/libs/instance-factories/views/templates/shared/base-generator.js.map +1 -0
- package/libs/instance-factories/views/templates/shared/base-generator.ts +608 -0
- package/libs/instance-factories/views/templates/shared/component-metadata.d.ts +254 -0
- package/libs/instance-factories/views/templates/shared/component-metadata.d.ts.map +1 -0
- package/libs/instance-factories/views/templates/shared/component-metadata.js +602 -0
- package/libs/instance-factories/views/templates/shared/component-metadata.js.map +1 -0
- package/libs/instance-factories/views/templates/shared/component-metadata.ts +803 -0
- package/libs/instance-factories/views/templates/shared/composite-pattern-types.ts +250 -0
- package/libs/instance-factories/views/templates/shared/composite-patterns.ts +535 -0
- package/libs/instance-factories/views/templates/shared/index.ts +68 -0
- package/libs/instance-factories/views/templates/shared/pattern-validator.ts +279 -0
- package/libs/instance-factories/views/templates/shared/property-mapper.d.ts +149 -0
- package/libs/instance-factories/views/templates/shared/property-mapper.d.ts.map +1 -0
- package/libs/instance-factories/views/templates/shared/property-mapper.js +580 -0
- package/libs/instance-factories/views/templates/shared/property-mapper.js.map +1 -0
- package/libs/instance-factories/views/templates/shared/property-mapper.ts +700 -0
- package/libs/instance-factories/views/templates/shared/syntax-mapper.d.ts +143 -0
- package/libs/instance-factories/views/templates/shared/syntax-mapper.d.ts.map +1 -0
- package/libs/instance-factories/views/templates/shared/syntax-mapper.js +420 -0
- package/libs/instance-factories/views/templates/shared/syntax-mapper.js.map +1 -0
- package/libs/instance-factories/views/templates/shared/syntax-mapper.ts +539 -0
- package/package.json +42 -0
- 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
|
+
}
|