@lssm/bundle.contractspec-workspace 0.0.0-canary-20251217083314 → 1.41.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/rolldown_runtime.js +1 -22
- package/dist/adapters/ai.js +1 -82
- package/dist/adapters/factory.js +1 -36
- package/dist/adapters/fs.js +1 -118
- package/dist/adapters/git.js +1 -54
- package/dist/adapters/index.js +1 -7
- package/dist/adapters/logger.js +1 -80
- package/dist/adapters/watcher.js +1 -69
- package/dist/adapters/workspace.js +2 -190
- package/dist/ai/agents/claude-code-agent.js +9 -146
- package/dist/ai/agents/cursor-agent.js +17 -286
- package/dist/ai/agents/index.js +1 -5
- package/dist/ai/agents/openai-codex-agent.js +8 -140
- package/dist/ai/agents/orchestrator.js +1 -142
- package/dist/ai/agents/simple-agent.js +4 -80
- package/dist/ai/client.js +1 -162
- package/dist/ai/index.js +1 -27
- package/dist/ai/prompts/code-generation.js +13 -55
- package/dist/ai/prompts/index.js +1 -12
- package/dist/ai/prompts/spec-creation.js +20 -61
- package/dist/ai/providers.js +1 -40
- package/dist/formatters/index.js +1 -18
- package/dist/formatters/json.js +1 -71
- package/dist/formatters/sarif.js +1 -163
- package/dist/formatters/text.js +2 -208
- package/dist/index.js +1 -81
- package/dist/services/agent-guide/adapters/claude-code.js +3 -144
- package/dist/services/agent-guide/adapters/cursor-cli.js +3 -135
- package/dist/services/agent-guide/adapters/generic-mcp.js +3 -159
- package/dist/services/agent-guide/adapters/index.js +1 -30
- package/dist/services/agent-guide/agent-guide-service.js +1 -148
- package/dist/services/agent-guide/index.js +1 -5
- package/dist/services/build.js +1 -140
- package/dist/services/ci-check/ci-check-service.js +1 -393
- package/dist/services/ci-check/index.js +1 -2
- package/dist/services/ci-check/types.js +1 -28
- package/dist/services/clean.js +1 -71
- package/dist/services/config.js +1 -76
- package/dist/services/deps.js +1 -62
- package/dist/services/diff.js +1 -33
- package/dist/services/doctor/checks/ai.js +2 -118
- package/dist/services/doctor/checks/cli.js +1 -146
- package/dist/services/doctor/checks/config.js +1 -170
- package/dist/services/doctor/checks/deps.js +1 -180
- package/dist/services/doctor/checks/index.js +1 -6
- package/dist/services/doctor/checks/mcp.js +1 -144
- package/dist/services/doctor/checks/workspace.js +1 -243
- package/dist/services/doctor/doctor-service.js +2 -115
- package/dist/services/doctor/index.js +1 -2
- package/dist/services/doctor/types.js +1 -26
- package/dist/services/implementation/discovery.js +2 -143
- package/dist/services/implementation/index.js +1 -2
- package/dist/services/implementation/resolver.js +1 -223
- package/dist/services/index.js +1 -53
- package/dist/services/integrity-diagram.js +6 -274
- package/dist/services/integrity.js +1 -272
- package/dist/services/list.js +1 -35
- package/dist/services/openapi/export-service.js +2 -51
- package/dist/services/openapi/import-service.js +1 -75
- package/dist/services/openapi/index.js +1 -4
- package/dist/services/openapi/sync-service.js +1 -121
- package/dist/services/openapi/validate-service.js +1 -130
- package/dist/services/regenerator.js +1 -23
- package/dist/services/registry.js +1 -73
- package/dist/services/setup/config-generators.js +26 -113
- package/dist/services/setup/file-merger.js +2 -60
- package/dist/services/setup/index.js +1 -4
- package/dist/services/setup/setup-service.js +1 -95
- package/dist/services/setup/targets/agents-md.js +1 -46
- package/dist/services/setup/targets/cli-config.js +1 -59
- package/dist/services/setup/targets/cursor-rules.js +1 -47
- package/dist/services/setup/targets/mcp-claude.js +1 -59
- package/dist/services/setup/targets/mcp-cursor.js +1 -58
- package/dist/services/setup/targets/vscode-settings.js +1 -62
- package/dist/services/setup/types.js +1 -26
- package/dist/services/sync.js +1 -62
- package/dist/services/test.js +1 -30
- package/dist/services/validate-implementation.js +1 -69
- package/dist/services/validate.js +1 -47
- package/dist/services/verification-cache/adapters/filesystem.js +1 -121
- package/dist/services/verification-cache/adapters/in-memory.js +1 -45
- package/dist/services/verification-cache/adapters/index.js +1 -3
- package/dist/services/verification-cache/adapters/workspace-state.js +1 -90
- package/dist/services/verification-cache/cache-service.js +1 -255
- package/dist/services/verification-cache/index.js +1 -6
- package/dist/services/verification-cache/types.js +1 -15
- package/dist/services/verify/ai-verifier.js +9 -336
- package/dist/services/verify/behavior-verifier.js +1 -185
- package/dist/services/verify/index.js +1 -4
- package/dist/services/verify/structure-verifier.js +2 -195
- package/dist/services/verify/verify-service.js +3 -203
- package/dist/services/watch.js +1 -31
- package/dist/services/workspace-info.js +2 -102
- package/dist/templates/app-config.template.js +28 -101
- package/dist/templates/data-view.template.js +27 -42
- package/dist/templates/event.template.js +14 -29
- package/dist/templates/experiment.template.js +51 -77
- package/dist/templates/handler.template.js +17 -53
- package/dist/templates/index.js +1 -36
- package/dist/templates/integration.template.js +50 -134
- package/dist/templates/knowledge.template.js +21 -62
- package/dist/templates/migration.template.js +26 -50
- package/dist/templates/operation.template.js +28 -44
- package/dist/templates/presentation.template.js +20 -46
- package/dist/templates/telemetry.template.js +53 -74
- package/dist/templates/workflow-runner.template.js +6 -12
- package/dist/templates/workflow.template.js +24 -51
- package/package.json +10 -15
- package/dist/adapters/ai.d.ts +0 -11
- package/dist/adapters/factory.d.ts +0 -28
- package/dist/adapters/fs.d.ts +0 -10
- package/dist/adapters/git.d.ts +0 -10
- package/dist/adapters/logger.d.ts +0 -17
- package/dist/adapters/watcher.d.ts +0 -10
- package/dist/adapters/workspace.d.ts +0 -93
- package/dist/ai/agents/claude-code-agent.d.ts +0 -21
- package/dist/ai/agents/cursor-agent.d.ts +0 -67
- package/dist/ai/agents/openai-codex-agent.d.ts +0 -21
- package/dist/ai/agents/orchestrator.d.ts +0 -49
- package/dist/ai/agents/simple-agent.d.ts +0 -16
- package/dist/ai/agents/types.d.ts +0 -35
- package/dist/ai/client.d.ts +0 -82
- package/dist/ai/index.d.ts +0 -16
- package/dist/ai/prompts/code-generation.d.ts +0 -25
- package/dist/ai/prompts/index.d.ts +0 -9
- package/dist/ai/prompts/spec-creation.d.ts +0 -28
- package/dist/ai/providers.d.ts +0 -28
- package/dist/formatters/index.d.ts +0 -10
- package/dist/formatters/json.d.ts +0 -88
- package/dist/formatters/sarif.d.ts +0 -100
- package/dist/formatters/text.d.ts +0 -34
- package/dist/index.d.ts +0 -66
- package/dist/libs/ai-providers/dist/factory.js +0 -154
- package/dist/libs/ai-providers/dist/index.js +0 -4
- package/dist/libs/ai-providers/dist/legacy.js +0 -72
- package/dist/libs/ai-providers/dist/models.js +0 -287
- package/dist/libs/ai-providers/dist/validation.js +0 -1
- package/dist/libs/contracts/dist/capabilities/openbanking.js +0 -88
- package/dist/libs/contracts/dist/client/index.js +0 -5
- package/dist/libs/contracts/dist/client/react/feature-render.js +0 -2
- package/dist/libs/contracts/dist/client/react/form-render.js +0 -4
- package/dist/libs/contracts/dist/client/react/index.js +0 -4
- package/dist/libs/contracts/dist/contract-registry/index.js +0 -1
- package/dist/libs/contracts/dist/contract-registry/schemas.js +0 -60
- package/dist/libs/contracts/dist/docs/PUBLISHING.docblock.js +0 -16
- package/dist/libs/contracts/dist/docs/accessibility_wcag_compliance_specs.docblock.js +0 -16
- package/dist/libs/contracts/dist/docs/index.js +0 -29
- package/dist/libs/contracts/dist/docs/presentations.js +0 -71
- package/dist/libs/contracts/dist/docs/registry.js +0 -44
- package/dist/libs/contracts/dist/docs/tech/PHASE_1_QUICKSTART.docblock.js +0 -16
- package/dist/libs/contracts/dist/docs/tech/PHASE_2_AI_NATIVE_OPERATIONS.docblock.js +0 -16
- package/dist/libs/contracts/dist/docs/tech/PHASE_3_AUTO_EVOLUTION.docblock.js +0 -16
- package/dist/libs/contracts/dist/docs/tech/PHASE_4_PERSONALIZATION_ENGINE.docblock.js +0 -16
- package/dist/libs/contracts/dist/docs/tech/PHASE_5_ZERO_TOUCH_OPERATIONS.docblock.js +0 -16
- package/dist/libs/contracts/dist/docs/tech/auth/better-auth-nextjs.docblock.js +0 -80
- package/dist/libs/contracts/dist/docs/tech/contracts/openapi-export.docblock.js +0 -57
- package/dist/libs/contracts/dist/docs/tech/lifecycle-stage-system.docblock.js +0 -16
- package/dist/libs/contracts/dist/docs/tech/llm/llm-integration.docblock.js +0 -357
- package/dist/libs/contracts/dist/docs/tech/mcp-endpoints.docblock.js +0 -37
- package/dist/libs/contracts/dist/docs/tech/presentation-runtime.docblock.js +0 -16
- package/dist/libs/contracts/dist/docs/tech/schema/README.docblock.js +0 -20
- package/dist/libs/contracts/dist/docs/tech/studio/learning-events.docblock.js +0 -48
- package/dist/libs/contracts/dist/docs/tech/studio/learning-journeys.docblock.js +0 -79
- package/dist/libs/contracts/dist/docs/tech/studio/platform-admin-panel.docblock.js +0 -84
- package/dist/libs/contracts/dist/docs/tech/studio/project-access-teams.docblock.js +0 -45
- package/dist/libs/contracts/dist/docs/tech/studio/project-routing.docblock.js +0 -67
- package/dist/libs/contracts/dist/docs/tech/studio/sandbox-unlogged.docblock.js +0 -40
- package/dist/libs/contracts/dist/docs/tech/studio/team-invitations.docblock.js +0 -69
- package/dist/libs/contracts/dist/docs/tech/studio/workspace-ops.docblock.js +0 -47
- package/dist/libs/contracts/dist/docs/tech/studio/workspaces.docblock.js +0 -62
- package/dist/libs/contracts/dist/docs/tech/telemetry-ingest.docblock.js +0 -155
- package/dist/libs/contracts/dist/docs/tech/templates/runtime.docblock.js +0 -20
- package/dist/libs/contracts/dist/docs/tech/vscode-extension.docblock.js +0 -101
- package/dist/libs/contracts/dist/docs/tech/workflows/overview.docblock.js +0 -20
- package/dist/libs/contracts/dist/events.js +0 -8
- package/dist/libs/contracts/dist/experiments/evaluator.js +0 -1
- package/dist/libs/contracts/dist/index.js +0 -72
- package/dist/libs/contracts/dist/install.js +0 -2
- package/dist/libs/contracts/dist/integrations/contracts.js +0 -377
- package/dist/libs/contracts/dist/integrations/index.js +0 -18
- package/dist/libs/contracts/dist/integrations/openbanking/contracts/accounts.js +0 -228
- package/dist/libs/contracts/dist/integrations/openbanking/contracts/balances.js +0 -159
- package/dist/libs/contracts/dist/integrations/openbanking/contracts/index.js +0 -3
- package/dist/libs/contracts/dist/integrations/openbanking/contracts/transactions.js +0 -210
- package/dist/libs/contracts/dist/integrations/openbanking/models.js +0 -242
- package/dist/libs/contracts/dist/integrations/openbanking/telemetry.js +0 -13
- package/dist/libs/contracts/dist/integrations/providers/elevenlabs.js +0 -52
- package/dist/libs/contracts/dist/integrations/providers/gcs-storage.js +0 -75
- package/dist/libs/contracts/dist/integrations/providers/gmail.js +0 -87
- package/dist/libs/contracts/dist/integrations/providers/google-calendar.js +0 -66
- package/dist/libs/contracts/dist/integrations/providers/index.js +0 -11
- package/dist/libs/contracts/dist/integrations/providers/mistral.js +0 -68
- package/dist/libs/contracts/dist/integrations/providers/postmark.js +0 -68
- package/dist/libs/contracts/dist/integrations/providers/powens.js +0 -116
- package/dist/libs/contracts/dist/integrations/providers/qdrant.js +0 -73
- package/dist/libs/contracts/dist/integrations/providers/registry.js +0 -10
- package/dist/libs/contracts/dist/integrations/providers/stripe.js +0 -83
- package/dist/libs/contracts/dist/integrations/providers/twilio-sms.js +0 -61
- package/dist/libs/contracts/dist/jsonschema.js +0 -24
- package/dist/libs/contracts/dist/knowledge/contracts.js +0 -306
- package/dist/libs/contracts/dist/knowledge/index.js +0 -7
- package/dist/libs/contracts/dist/knowledge/spaces/email-threads.js +0 -34
- package/dist/libs/contracts/dist/knowledge/spaces/financial-docs.js +0 -34
- package/dist/libs/contracts/dist/knowledge/spaces/financial-overview.js +0 -38
- package/dist/libs/contracts/dist/knowledge/spaces/index.js +0 -6
- package/dist/libs/contracts/dist/knowledge/spaces/product-canon.js +0 -34
- package/dist/libs/contracts/dist/knowledge/spaces/support-faq.js +0 -37
- package/dist/libs/contracts/dist/knowledge/spaces/uploaded-docs.js +0 -34
- package/dist/libs/contracts/dist/llm/exporters.js +0 -352
- package/dist/libs/contracts/dist/llm/index.js +0 -2
- package/dist/libs/contracts/dist/llm/prompts.js +0 -211
- package/dist/libs/contracts/dist/onboarding-base.js +0 -196
- package/dist/libs/contracts/dist/openapi.js +0 -75
- package/dist/libs/contracts/dist/ownership.js +0 -21
- package/dist/libs/contracts/dist/presentations.js +0 -1
- package/dist/libs/contracts/dist/presentations.v2.js +0 -11
- package/dist/libs/contracts/dist/prompt.js +0 -1
- package/dist/libs/contracts/dist/promptRegistry.js +0 -1
- package/dist/libs/contracts/dist/regenerator/index.js +0 -2
- package/dist/libs/contracts/dist/regenerator/service.js +0 -92
- package/dist/libs/contracts/dist/regenerator/utils.js +0 -51
- package/dist/libs/contracts/dist/registry.js +0 -208
- package/dist/libs/contracts/dist/resources.js +0 -1
- package/dist/libs/contracts/dist/schema/dist/EnumType.js +0 -2
- package/dist/libs/contracts/dist/schema/dist/FieldType.js +0 -49
- package/dist/libs/contracts/dist/schema/dist/ScalarTypeEnum.js +0 -236
- package/dist/libs/contracts/dist/schema/dist/SchemaModel.js +0 -34
- package/dist/libs/contracts/dist/schema/dist/entity/defineEntity.js +0 -1
- package/dist/libs/contracts/dist/schema/dist/entity/index.js +0 -2
- package/dist/libs/contracts/dist/schema/dist/entity/types.js +0 -1
- package/dist/libs/contracts/dist/schema/dist/index.js +0 -6
- package/dist/libs/contracts/dist/server/graphql-pothos.js +0 -6
- package/dist/libs/contracts/dist/server/index.js +0 -8
- package/dist/libs/contracts/dist/server/mcp/createMcpServer.js +0 -4
- package/dist/libs/contracts/dist/server/mcp/registerPresentations.js +0 -2
- package/dist/libs/contracts/dist/server/mcp/registerPrompts.js +0 -1
- package/dist/libs/contracts/dist/server/mcp/registerResources.js +0 -2
- package/dist/libs/contracts/dist/server/mcp/registerTools.js +0 -1
- package/dist/libs/contracts/dist/server/provider-mcp.js +0 -1
- package/dist/libs/contracts/dist/server/rest-elysia.js +0 -1
- package/dist/libs/contracts/dist/server/rest-express.js +0 -1
- package/dist/libs/contracts/dist/server/rest-generic.js +0 -1
- package/dist/libs/contracts/dist/server/rest-next-app.js +0 -1
- package/dist/libs/contracts/dist/server/rest-next-pages.js +0 -1
- package/dist/libs/contracts/dist/spec.js +0 -35
- package/dist/libs/contracts/dist/telemetry/index.js +0 -1
- package/dist/libs/contracts/dist/telemetry/tracker.js +0 -1
- package/dist/libs/contracts/dist/tests/index.js +0 -1
- package/dist/libs/contracts/dist/tests/runner.js +0 -150
- package/dist/libs/contracts/dist/workflow/index.js +0 -1
- package/dist/libs/contracts/dist/workflow/runner.js +0 -1
- package/dist/libs/contracts-transformers/dist/common/utils.js +0 -47
- package/dist/libs/contracts-transformers/dist/openapi/exporter.js +0 -1
- package/dist/libs/contracts-transformers/dist/openapi/importer.js +0 -255
- package/dist/libs/contracts-transformers/dist/openapi/index.js +0 -4
- package/dist/libs/contracts-transformers/dist/openapi/parser.js +0 -231
- package/dist/libs/contracts-transformers/dist/openapi/schema-converter.js +0 -201
- package/dist/modules/contractspec-workspace/dist/ai/code-generation.js +0 -137
- package/dist/modules/contractspec-workspace/dist/ai/spec-creation.js +0 -101
- package/dist/modules/contractspec-workspace/dist/analysis/deps/graph.js +0 -84
- package/dist/modules/contractspec-workspace/dist/analysis/deps/parse-imports.js +0 -30
- package/dist/modules/contractspec-workspace/dist/analysis/diff/semantic.js +0 -96
- package/dist/modules/contractspec-workspace/dist/analysis/feature-scan.js +0 -151
- package/dist/modules/contractspec-workspace/dist/analysis/spec-scan.js +0 -344
- package/dist/modules/contractspec-workspace/dist/analysis/validate/spec-structure.js +0 -122
- package/dist/modules/contractspec-workspace/dist/templates/app-config.js +0 -105
- package/dist/modules/contractspec-workspace/dist/templates/data-view.js +0 -68
- package/dist/modules/contractspec-workspace/dist/templates/event.js +0 -38
- package/dist/modules/contractspec-workspace/dist/templates/experiment.js +0 -87
- package/dist/modules/contractspec-workspace/dist/templates/handler.js +0 -95
- package/dist/modules/contractspec-workspace/dist/templates/integration-utils.js +0 -104
- package/dist/modules/contractspec-workspace/dist/templates/integration.js +0 -62
- package/dist/modules/contractspec-workspace/dist/templates/knowledge.js +0 -68
- package/dist/modules/contractspec-workspace/dist/templates/migration.js +0 -60
- package/dist/modules/contractspec-workspace/dist/templates/operation.js +0 -100
- package/dist/modules/contractspec-workspace/dist/templates/presentation.js +0 -78
- package/dist/modules/contractspec-workspace/dist/templates/telemetry.js +0 -89
- package/dist/modules/contractspec-workspace/dist/templates/utils.js +0 -38
- package/dist/modules/contractspec-workspace/dist/templates/workflow-runner.js +0 -48
- package/dist/modules/contractspec-workspace/dist/templates/workflow.js +0 -67
- package/dist/modules/contractspec-workspace/dist/types/generation-types.js +0 -20
- package/dist/ports/ai.d.ts +0 -58
- package/dist/ports/fs.d.ts +0 -80
- package/dist/ports/git.d.ts +0 -32
- package/dist/ports/logger.d.ts +0 -87
- package/dist/ports/watcher.d.ts +0 -51
- package/dist/services/agent-guide/adapters/claude-code.d.ts +0 -34
- package/dist/services/agent-guide/adapters/cursor-cli.d.ts +0 -38
- package/dist/services/agent-guide/adapters/generic-mcp.d.ts +0 -52
- package/dist/services/agent-guide/adapters/index.d.ts +0 -22
- package/dist/services/agent-guide/agent-guide-service.d.ts +0 -55
- package/dist/services/agent-guide/types.d.ts +0 -57
- package/dist/services/build.d.ts +0 -58
- package/dist/services/ci-check/ci-check-service.d.ts +0 -15
- package/dist/services/ci-check/types.d.ts +0 -142
- package/dist/services/clean.d.ts +0 -40
- package/dist/services/config.d.ts +0 -25
- package/dist/services/deps.d.ts +0 -52
- package/dist/services/diff.d.ts +0 -33
- package/dist/services/doctor/doctor-service.d.ts +0 -23
- package/dist/services/doctor/types.d.ts +0 -117
- package/dist/services/implementation/discovery.d.ts +0 -29
- package/dist/services/implementation/resolver.d.ts +0 -43
- package/dist/services/implementation/types.d.ts +0 -78
- package/dist/services/integrity-diagram.d.ts +0 -35
- package/dist/services/integrity.d.ts +0 -133
- package/dist/services/list.d.ts +0 -30
- package/dist/services/openapi/export-service.d.ts +0 -52
- package/dist/services/openapi/import-service.d.ts +0 -15
- package/dist/services/openapi/sync-service.d.ts +0 -18
- package/dist/services/openapi/types.d.ts +0 -184
- package/dist/services/openapi/validate-service.d.ts +0 -15
- package/dist/services/regenerator.d.ts +0 -17
- package/dist/services/registry.d.ts +0 -52
- package/dist/services/setup/config-generators.d.ts +0 -41
- package/dist/services/setup/file-merger.d.ts +0 -26
- package/dist/services/setup/setup-service.d.ts +0 -11
- package/dist/services/setup/types.d.ts +0 -84
- package/dist/services/sync.d.ts +0 -40
- package/dist/services/test.d.ts +0 -14
- package/dist/services/validate-implementation.d.ts +0 -31
- package/dist/services/validate.d.ts +0 -40
- package/dist/services/verification-cache/adapters/filesystem.d.ts +0 -45
- package/dist/services/verification-cache/adapters/in-memory.d.ts +0 -26
- package/dist/services/verification-cache/adapters/workspace-state.d.ts +0 -48
- package/dist/services/verification-cache/cache-service.d.ts +0 -69
- package/dist/services/verification-cache/types.d.ts +0 -123
- package/dist/services/verify/ai-verifier.d.ts +0 -24
- package/dist/services/verify/behavior-verifier.d.ts +0 -11
- package/dist/services/verify/structure-verifier.d.ts +0 -11
- package/dist/services/verify/types.d.ts +0 -136
- package/dist/services/verify/verify-service.d.ts +0 -59
- package/dist/services/watch.d.ts +0 -24
- package/dist/services/workspace-info.d.ts +0 -61
- package/dist/templates/app-config.template.d.ts +0 -6
- package/dist/templates/data-view.template.d.ts +0 -6
- package/dist/templates/event.template.d.ts +0 -10
- package/dist/templates/experiment.template.d.ts +0 -6
- package/dist/templates/handler.template.d.ts +0 -15
- package/dist/templates/index.d.ts +0 -20
- package/dist/templates/integration.template.d.ts +0 -6
- package/dist/templates/knowledge.template.d.ts +0 -6
- package/dist/templates/migration.template.d.ts +0 -6
- package/dist/templates/operation.template.d.ts +0 -10
- package/dist/templates/presentation.template.d.ts +0 -10
- package/dist/templates/telemetry.template.d.ts +0 -6
- package/dist/templates/workflow-runner.template.d.ts +0 -15
- package/dist/templates/workflow.template.d.ts +0 -6
- package/dist/types/config.d.ts +0 -33
- package/dist/types.d.ts +0 -323
|
@@ -1,274 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
case "feature-map": return generateFeatureMapDiagram(result, options);
|
|
8
|
-
case "orphans": return generateOrphansDiagram(result, options);
|
|
9
|
-
case "dependencies": return generateDependenciesDiagram(result, options);
|
|
10
|
-
case "full": return generateFullDiagram(result, options);
|
|
11
|
-
default: return generateFeatureMapDiagram(result, options);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Generate a feature map diagram showing features and their linked specs.
|
|
16
|
-
*/
|
|
17
|
-
function generateFeatureMapDiagram(result, options) {
|
|
18
|
-
const { direction = "LR", showVersions = true, maxNodes = 50 } = options;
|
|
19
|
-
const lines = [`flowchart ${direction}`];
|
|
20
|
-
let features = result.features;
|
|
21
|
-
if (options.featureKeys && options.featureKeys.length > 0) features = features.filter((f) => options.featureKeys.includes(f.key));
|
|
22
|
-
let nodeCount = 0;
|
|
23
|
-
if (features.length > 0) {
|
|
24
|
-
lines.push(" subgraph features [Features]");
|
|
25
|
-
for (const feature of features) {
|
|
26
|
-
if (nodeCount >= maxNodes) break;
|
|
27
|
-
const nodeId = sanitizeId(`F_${feature.key}`);
|
|
28
|
-
const label = feature.title ?? feature.key;
|
|
29
|
-
lines.push(` ${nodeId}["${escapeLabel(label)}"]`);
|
|
30
|
-
nodeCount++;
|
|
31
|
-
}
|
|
32
|
-
lines.push(" end");
|
|
33
|
-
}
|
|
34
|
-
const ops = getReferencedSpecs(features, "operations", result.inventory);
|
|
35
|
-
if (ops.length > 0 && nodeCount < maxNodes) {
|
|
36
|
-
lines.push(" subgraph ops [Operations]");
|
|
37
|
-
for (const op of ops) {
|
|
38
|
-
if (nodeCount >= maxNodes) break;
|
|
39
|
-
const nodeId = sanitizeId(`O_${op.name}_v${op.version}`);
|
|
40
|
-
const label = showVersions ? `${op.name}.v${op.version}` : op.name;
|
|
41
|
-
lines.push(` ${nodeId}["${escapeLabel(label)}"]`);
|
|
42
|
-
nodeCount++;
|
|
43
|
-
}
|
|
44
|
-
lines.push(" end");
|
|
45
|
-
}
|
|
46
|
-
const events = getReferencedSpecs(features, "events", result.inventory);
|
|
47
|
-
if (events.length > 0 && nodeCount < maxNodes) {
|
|
48
|
-
lines.push(" subgraph events [Events]");
|
|
49
|
-
for (const event of events) {
|
|
50
|
-
if (nodeCount >= maxNodes) break;
|
|
51
|
-
const nodeId = sanitizeId(`E_${event.name}_v${event.version}`);
|
|
52
|
-
const label = showVersions ? `${event.name}.v${event.version}` : event.name;
|
|
53
|
-
lines.push(` ${nodeId}["${escapeLabel(label)}"]`);
|
|
54
|
-
nodeCount++;
|
|
55
|
-
}
|
|
56
|
-
lines.push(" end");
|
|
57
|
-
}
|
|
58
|
-
const presentations = getReferencedSpecs(features, "presentations", result.inventory);
|
|
59
|
-
if (presentations.length > 0 && nodeCount < maxNodes) {
|
|
60
|
-
lines.push(" subgraph presentations [Presentations]");
|
|
61
|
-
for (const pres of presentations) {
|
|
62
|
-
if (nodeCount >= maxNodes) break;
|
|
63
|
-
const nodeId = sanitizeId(`P_${pres.name}_v${pres.version}`);
|
|
64
|
-
const label = showVersions ? `${pres.name}.v${pres.version}` : pres.name;
|
|
65
|
-
lines.push(` ${nodeId}["${escapeLabel(label)}"]`);
|
|
66
|
-
nodeCount++;
|
|
67
|
-
}
|
|
68
|
-
lines.push(" end");
|
|
69
|
-
}
|
|
70
|
-
for (const feature of features) {
|
|
71
|
-
const featureId = sanitizeId(`F_${feature.key}`);
|
|
72
|
-
for (const op of feature.operations) {
|
|
73
|
-
const opId = sanitizeId(`O_${op.name}_v${op.version}`);
|
|
74
|
-
lines.push(` ${featureId} --> ${opId}`);
|
|
75
|
-
}
|
|
76
|
-
for (const event of feature.events) {
|
|
77
|
-
const eventId = sanitizeId(`E_${event.name}_v${event.version}`);
|
|
78
|
-
lines.push(` ${featureId} -.-> ${eventId}`);
|
|
79
|
-
}
|
|
80
|
-
for (const pres of feature.presentations) {
|
|
81
|
-
const presId = sanitizeId(`P_${pres.name}_v${pres.version}`);
|
|
82
|
-
lines.push(` ${featureId} --> ${presId}`);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return lines.join("\n");
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Generate a diagram highlighting orphaned specs.
|
|
89
|
-
*/
|
|
90
|
-
function generateOrphansDiagram(result, options) {
|
|
91
|
-
const { direction = "TB", showVersions = true, maxNodes = 50 } = options;
|
|
92
|
-
const lines = [`flowchart ${direction}`];
|
|
93
|
-
const linkedOps = /* @__PURE__ */ new Set();
|
|
94
|
-
const linkedEvents = /* @__PURE__ */ new Set();
|
|
95
|
-
const linkedPres = /* @__PURE__ */ new Set();
|
|
96
|
-
for (const feature of result.features) {
|
|
97
|
-
for (const op of feature.operations) linkedOps.add(`${op.name}.v${op.version}`);
|
|
98
|
-
for (const event of feature.events) linkedEvents.add(`${event.name}.v${event.version}`);
|
|
99
|
-
for (const pres of feature.presentations) linkedPres.add(`${pres.name}.v${pres.version}`);
|
|
100
|
-
}
|
|
101
|
-
let nodeCount = 0;
|
|
102
|
-
if (result.features.length > 0) {
|
|
103
|
-
lines.push(" subgraph features [Features]");
|
|
104
|
-
for (const feature of result.features) {
|
|
105
|
-
if (nodeCount >= maxNodes) break;
|
|
106
|
-
const nodeId = sanitizeId(`F_${feature.key}`);
|
|
107
|
-
lines.push(` ${nodeId}["${escapeLabel(feature.title ?? feature.key)}"]`);
|
|
108
|
-
nodeCount++;
|
|
109
|
-
}
|
|
110
|
-
lines.push(" end");
|
|
111
|
-
}
|
|
112
|
-
if (result.orphanedSpecs.length > 0) {
|
|
113
|
-
lines.push(" subgraph orphaned [Orphaned Specs]");
|
|
114
|
-
for (const spec of result.orphanedSpecs) {
|
|
115
|
-
if (nodeCount >= maxNodes) break;
|
|
116
|
-
const nodeId = sanitizeId(`orphan_${spec.type}_${spec.name}_v${spec.version}`);
|
|
117
|
-
const label = showVersions ? `${spec.name}.v${spec.version}` : spec.name;
|
|
118
|
-
lines.push(` ${nodeId}["${escapeLabel(label)}"]`);
|
|
119
|
-
nodeCount++;
|
|
120
|
-
}
|
|
121
|
-
lines.push(" end");
|
|
122
|
-
}
|
|
123
|
-
const allLinked = [];
|
|
124
|
-
for (const key of linkedOps) {
|
|
125
|
-
const [name, version] = parseSpecKey(key);
|
|
126
|
-
if (name && version) allLinked.push({
|
|
127
|
-
type: "operation",
|
|
128
|
-
name,
|
|
129
|
-
version
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
for (const key of linkedEvents) {
|
|
133
|
-
const [name, version] = parseSpecKey(key);
|
|
134
|
-
if (name && version) allLinked.push({
|
|
135
|
-
type: "event",
|
|
136
|
-
name,
|
|
137
|
-
version
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
for (const key of linkedPres) {
|
|
141
|
-
const [name, version] = parseSpecKey(key);
|
|
142
|
-
if (name && version) allLinked.push({
|
|
143
|
-
type: "presentation",
|
|
144
|
-
name,
|
|
145
|
-
version
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
if (allLinked.length > 0 && nodeCount < maxNodes) {
|
|
149
|
-
lines.push(" subgraph linked [Linked Specs]");
|
|
150
|
-
for (const spec of allLinked) {
|
|
151
|
-
if (nodeCount >= maxNodes) break;
|
|
152
|
-
const nodeId = sanitizeId(`${spec.type}_${spec.name}_v${spec.version}`);
|
|
153
|
-
const label = showVersions ? `${spec.name}.v${spec.version}` : spec.name;
|
|
154
|
-
lines.push(` ${nodeId}["${escapeLabel(label)}"]`);
|
|
155
|
-
nodeCount++;
|
|
156
|
-
}
|
|
157
|
-
lines.push(" end");
|
|
158
|
-
}
|
|
159
|
-
for (const feature of result.features) {
|
|
160
|
-
const featureId = sanitizeId(`F_${feature.key}`);
|
|
161
|
-
for (const op of feature.operations) {
|
|
162
|
-
const opId = sanitizeId(`operation_${op.name}_v${op.version}`);
|
|
163
|
-
lines.push(` ${featureId} --> ${opId}`);
|
|
164
|
-
}
|
|
165
|
-
for (const event of feature.events) {
|
|
166
|
-
const eventId = sanitizeId(`event_${event.name}_v${event.version}`);
|
|
167
|
-
lines.push(` ${featureId} -.-> ${eventId}`);
|
|
168
|
-
}
|
|
169
|
-
for (const pres of feature.presentations) {
|
|
170
|
-
const presId = sanitizeId(`presentation_${pres.name}_v${pres.version}`);
|
|
171
|
-
lines.push(` ${featureId} --> ${presId}`);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return lines.join("\n");
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Generate a dependency diagram showing spec relationships.
|
|
178
|
-
*/
|
|
179
|
-
function generateDependenciesDiagram(result, options) {
|
|
180
|
-
const { direction = "TB", showVersions = true, maxNodes = 50 } = options;
|
|
181
|
-
const lines = [`flowchart ${direction}`];
|
|
182
|
-
let nodeCount = 0;
|
|
183
|
-
for (const feature of result.features) {
|
|
184
|
-
if (nodeCount >= maxNodes) break;
|
|
185
|
-
const featureId = sanitizeId(`F_${feature.key}`);
|
|
186
|
-
lines.push(` ${featureId}["${escapeLabel(feature.title ?? feature.key)}"]`);
|
|
187
|
-
nodeCount++;
|
|
188
|
-
for (const op of feature.operations) {
|
|
189
|
-
if (nodeCount >= maxNodes) break;
|
|
190
|
-
const opId = sanitizeId(`O_${op.name}_v${op.version}`);
|
|
191
|
-
const label = showVersions ? `${op.name}.v${op.version}` : op.name;
|
|
192
|
-
lines.push(` ${opId}["${escapeLabel(label)}"]`);
|
|
193
|
-
lines.push(` ${featureId} --> ${opId}`);
|
|
194
|
-
nodeCount++;
|
|
195
|
-
}
|
|
196
|
-
for (const event of feature.events) {
|
|
197
|
-
if (nodeCount >= maxNodes) break;
|
|
198
|
-
const eventId = sanitizeId(`E_${event.name}_v${event.version}`);
|
|
199
|
-
const label = showVersions ? `${event.name}.v${event.version}` : event.name;
|
|
200
|
-
lines.push(` ${eventId}["${escapeLabel(label)}"]`);
|
|
201
|
-
lines.push(` ${featureId} -.-> ${eventId}`);
|
|
202
|
-
nodeCount++;
|
|
203
|
-
}
|
|
204
|
-
for (const pres of feature.presentations) {
|
|
205
|
-
if (nodeCount >= maxNodes) break;
|
|
206
|
-
const presId = sanitizeId(`P_${pres.name}_v${pres.version}`);
|
|
207
|
-
const label = showVersions ? `${pres.name}.v${pres.version}` : pres.name;
|
|
208
|
-
lines.push(` ${presId}["${escapeLabel(label)}"]`);
|
|
209
|
-
lines.push(` ${featureId} --> ${presId}`);
|
|
210
|
-
nodeCount++;
|
|
211
|
-
}
|
|
212
|
-
for (const link of feature.opToPresentationLinks) {
|
|
213
|
-
const opId = sanitizeId(`O_${link.op.name}_v${link.op.version}`);
|
|
214
|
-
const presId = sanitizeId(`P_${link.pres.name}_v${link.pres.version}`);
|
|
215
|
-
lines.push(` ${opId} --> ${presId}`);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
return lines.join("\n");
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Generate a full diagram with all relationships.
|
|
222
|
-
*/
|
|
223
|
-
function generateFullDiagram(result, options) {
|
|
224
|
-
const featureMap = generateFeatureMapDiagram(result, options);
|
|
225
|
-
if (result.orphanedSpecs.length === 0) return featureMap;
|
|
226
|
-
const lines = featureMap.split("\n");
|
|
227
|
-
lines.push(" subgraph orphaned [Orphaned Specs]");
|
|
228
|
-
for (const spec of result.orphanedSpecs.slice(0, 20)) {
|
|
229
|
-
const nodeId = sanitizeId(`orphan_${spec.type}_${spec.name}_v${spec.version}`);
|
|
230
|
-
const label = `${spec.name}.v${spec.version}`;
|
|
231
|
-
lines.push(` ${nodeId}["${escapeLabel(label)}"]:::orphan`);
|
|
232
|
-
}
|
|
233
|
-
lines.push(" end");
|
|
234
|
-
lines.push(" classDef orphan stroke-dasharray: 5 5");
|
|
235
|
-
return lines.join("\n");
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Get referenced specs from features.
|
|
239
|
-
*/
|
|
240
|
-
function getReferencedSpecs(features, field, _inventory) {
|
|
241
|
-
const seen = /* @__PURE__ */ new Set();
|
|
242
|
-
const result = [];
|
|
243
|
-
for (const feature of features) for (const ref of feature[field]) {
|
|
244
|
-
const key = `${ref.name}.v${ref.version}`;
|
|
245
|
-
if (!seen.has(key)) {
|
|
246
|
-
seen.add(key);
|
|
247
|
-
result.push(ref);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
return result;
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Parse a spec key like "name.v1" into [name, version].
|
|
254
|
-
*/
|
|
255
|
-
function parseSpecKey(key) {
|
|
256
|
-
const match = key.match(/^(.+)\.v(\d+)$/);
|
|
257
|
-
if (!match) return [void 0, void 0];
|
|
258
|
-
return [match[1], Number(match[2])];
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* Sanitize an ID for use in Mermaid.
|
|
262
|
-
*/
|
|
263
|
-
function sanitizeId(id) {
|
|
264
|
-
return id.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Escape a label for use in Mermaid.
|
|
268
|
-
*/
|
|
269
|
-
function escapeLabel(label) {
|
|
270
|
-
return label.replace(/"/g, "'").replace(/\[/g, "(").replace(/\]/g, ")").replace(/\{/g, "(").replace(/\}/g, ")");
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
//#endregion
|
|
274
|
-
export { generateMermaidDiagram };
|
|
1
|
+
function e(e,a=`feature-map`,o={}){switch(a){case`feature-map`:return t(e,o);case`orphans`:return n(e,o);case`dependencies`:return r(e,o);case`full`:return i(e,o);default:return t(e,o)}}function t(e,t){let{direction:n=`LR`,showVersions:r=!0,maxNodes:i=50}=t,o=[`flowchart ${n}`],l=e.features;t.featureKeys&&t.featureKeys.length>0&&(l=l.filter(e=>t.featureKeys.includes(e.key)));let u=0;if(l.length>0){o.push(` subgraph features [Features]`);for(let e of l){if(u>=i)break;let t=s(`F_${e.key}`),n=e.title??e.key;o.push(` ${t}["${c(n)}"]`),u++}o.push(` end`)}let d=a(l,`operations`,e.inventory);if(d.length>0&&u<i){o.push(` subgraph ops [Operations]`);for(let e of d){if(u>=i)break;let t=s(`O_${e.name}_v${e.version}`),n=r?`${e.name}.v${e.version}`:e.name;o.push(` ${t}["${c(n)}"]`),u++}o.push(` end`)}let f=a(l,`events`,e.inventory);if(f.length>0&&u<i){o.push(` subgraph events [Events]`);for(let e of f){if(u>=i)break;let t=s(`E_${e.name}_v${e.version}`),n=r?`${e.name}.v${e.version}`:e.name;o.push(` ${t}["${c(n)}"]`),u++}o.push(` end`)}let p=a(l,`presentations`,e.inventory);if(p.length>0&&u<i){o.push(` subgraph presentations [Presentations]`);for(let e of p){if(u>=i)break;let t=s(`P_${e.name}_v${e.version}`),n=r?`${e.name}.v${e.version}`:e.name;o.push(` ${t}["${c(n)}"]`),u++}o.push(` end`)}for(let e of l){let t=s(`F_${e.key}`);for(let n of e.operations){let e=s(`O_${n.name}_v${n.version}`);o.push(` ${t} --> ${e}`)}for(let n of e.events){let e=s(`E_${n.name}_v${n.version}`);o.push(` ${t} -.-> ${e}`)}for(let n of e.presentations){let e=s(`P_${n.name}_v${n.version}`);o.push(` ${t} --> ${e}`)}}return o.join(`
|
|
2
|
+
`)}function n(e,t){let{direction:n=`TB`,showVersions:r=!0,maxNodes:i=50}=t,a=[`flowchart ${n}`],l=new Set,u=new Set,d=new Set;for(let t of e.features){for(let e of t.operations)l.add(`${e.name}.v${e.version}`);for(let e of t.events)u.add(`${e.name}.v${e.version}`);for(let e of t.presentations)d.add(`${e.name}.v${e.version}`)}let f=0;if(e.features.length>0){a.push(` subgraph features [Features]`);for(let t of e.features){if(f>=i)break;let e=s(`F_${t.key}`);a.push(` ${e}["${c(t.title??t.key)}"]`),f++}a.push(` end`)}if(e.orphanedSpecs.length>0){a.push(` subgraph orphaned [Orphaned Specs]`);for(let t of e.orphanedSpecs){if(f>=i)break;let e=s(`orphan_${t.type}_${t.name}_v${t.version}`),n=r?`${t.name}.v${t.version}`:t.name;a.push(` ${e}["${c(n)}"]`),f++}a.push(` end`)}let p=[];for(let e of l){let[t,n]=o(e);t&&n&&p.push({type:`operation`,name:t,version:n})}for(let e of u){let[t,n]=o(e);t&&n&&p.push({type:`event`,name:t,version:n})}for(let e of d){let[t,n]=o(e);t&&n&&p.push({type:`presentation`,name:t,version:n})}if(p.length>0&&f<i){a.push(` subgraph linked [Linked Specs]`);for(let e of p){if(f>=i)break;let t=s(`${e.type}_${e.name}_v${e.version}`),n=r?`${e.name}.v${e.version}`:e.name;a.push(` ${t}["${c(n)}"]`),f++}a.push(` end`)}for(let t of e.features){let e=s(`F_${t.key}`);for(let n of t.operations){let t=s(`operation_${n.name}_v${n.version}`);a.push(` ${e} --> ${t}`)}for(let n of t.events){let t=s(`event_${n.name}_v${n.version}`);a.push(` ${e} -.-> ${t}`)}for(let n of t.presentations){let t=s(`presentation_${n.name}_v${n.version}`);a.push(` ${e} --> ${t}`)}}return a.join(`
|
|
3
|
+
`)}function r(e,t){let{direction:n=`TB`,showVersions:r=!0,maxNodes:i=50}=t,a=[`flowchart ${n}`],o=0;for(let t of e.features){if(o>=i)break;let e=s(`F_${t.key}`);a.push(` ${e}["${c(t.title??t.key)}"]`),o++;for(let n of t.operations){if(o>=i)break;let t=s(`O_${n.name}_v${n.version}`),l=r?`${n.name}.v${n.version}`:n.name;a.push(` ${t}["${c(l)}"]`),a.push(` ${e} --> ${t}`),o++}for(let n of t.events){if(o>=i)break;let t=s(`E_${n.name}_v${n.version}`),l=r?`${n.name}.v${n.version}`:n.name;a.push(` ${t}["${c(l)}"]`),a.push(` ${e} -.-> ${t}`),o++}for(let n of t.presentations){if(o>=i)break;let t=s(`P_${n.name}_v${n.version}`),l=r?`${n.name}.v${n.version}`:n.name;a.push(` ${t}["${c(l)}"]`),a.push(` ${e} --> ${t}`),o++}for(let e of t.opToPresentationLinks){let t=s(`O_${e.op.name}_v${e.op.version}`),n=s(`P_${e.pres.name}_v${e.pres.version}`);a.push(` ${t} --> ${n}`)}}return a.join(`
|
|
4
|
+
`)}function i(e,n){let r=t(e,n);if(e.orphanedSpecs.length===0)return r;let i=r.split(`
|
|
5
|
+
`);i.push(` subgraph orphaned [Orphaned Specs]`);for(let t of e.orphanedSpecs.slice(0,20)){let e=s(`orphan_${t.type}_${t.name}_v${t.version}`),n=`${t.name}.v${t.version}`;i.push(` ${e}["${c(n)}"]:::orphan`)}return i.push(` end`),i.push(` classDef orphan stroke-dasharray: 5 5`),i.join(`
|
|
6
|
+
`)}function a(e,t,n){let r=new Set,i=[];for(let n of e)for(let e of n[t]){let t=`${e.name}.v${e.version}`;r.has(t)||(r.add(t),i.push(e))}return i}function o(e){let t=e.match(/^(.+)\.v(\d+)$/);return t?[t[1],Number(t[2])]:[void 0,void 0]}function s(e){return e.replace(/[^a-zA-Z0-9_]/g,`_`)}function c(e){return e.replace(/"/g,`'`).replace(/\[/g,`(`).replace(/\]/g,`)`).replace(/\{/g,`(`).replace(/\}/g,`)`)}export{e as generateMermaidDiagram};
|
|
@@ -1,272 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { isFeatureFile, scanFeatureSource } from "../modules/contractspec-workspace/dist/analysis/feature-scan.js";
|
|
3
|
-
|
|
4
|
-
//#region src/services/integrity.ts
|
|
5
|
-
/**
|
|
6
|
-
* Contract integrity analysis service.
|
|
7
|
-
*
|
|
8
|
-
* Analyzes contract specs and features to detect:
|
|
9
|
-
* - Orphaned specs (not linked to any feature)
|
|
10
|
-
* - Unresolved references (broken event/op/presentation refs)
|
|
11
|
-
* - Feature coverage metrics
|
|
12
|
-
*/
|
|
13
|
-
/**
|
|
14
|
-
* Build a spec key from name and version.
|
|
15
|
-
*/
|
|
16
|
-
function specKey(name, version) {
|
|
17
|
-
return `${name}.v${version}`;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Create an empty spec inventory.
|
|
21
|
-
*/
|
|
22
|
-
function createEmptyInventory() {
|
|
23
|
-
return {
|
|
24
|
-
operations: /* @__PURE__ */ new Map(),
|
|
25
|
-
events: /* @__PURE__ */ new Map(),
|
|
26
|
-
presentations: /* @__PURE__ */ new Map(),
|
|
27
|
-
capabilities: /* @__PURE__ */ new Map(),
|
|
28
|
-
workflows: /* @__PURE__ */ new Map(),
|
|
29
|
-
dataViews: /* @__PURE__ */ new Map(),
|
|
30
|
-
forms: /* @__PURE__ */ new Map(),
|
|
31
|
-
migrations: /* @__PURE__ */ new Map(),
|
|
32
|
-
experiments: /* @__PURE__ */ new Map(),
|
|
33
|
-
integrations: /* @__PURE__ */ new Map(),
|
|
34
|
-
knowledge: /* @__PURE__ */ new Map(),
|
|
35
|
-
telemetry: /* @__PURE__ */ new Map(),
|
|
36
|
-
appConfigs: /* @__PURE__ */ new Map(),
|
|
37
|
-
policies: /* @__PURE__ */ new Map(),
|
|
38
|
-
testSpecs: /* @__PURE__ */ new Map()
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Get the inventory map for a spec type.
|
|
43
|
-
*/
|
|
44
|
-
function getInventoryMap(inventory, specType) {
|
|
45
|
-
return {
|
|
46
|
-
operation: inventory.operations,
|
|
47
|
-
event: inventory.events,
|
|
48
|
-
presentation: inventory.presentations,
|
|
49
|
-
capability: inventory.capabilities,
|
|
50
|
-
workflow: inventory.workflows,
|
|
51
|
-
"data-view": inventory.dataViews,
|
|
52
|
-
form: inventory.forms,
|
|
53
|
-
migration: inventory.migrations,
|
|
54
|
-
experiment: inventory.experiments,
|
|
55
|
-
integration: inventory.integrations,
|
|
56
|
-
knowledge: inventory.knowledge,
|
|
57
|
-
telemetry: inventory.telemetry,
|
|
58
|
-
"app-config": inventory.appConfigs,
|
|
59
|
-
policy: inventory.policies,
|
|
60
|
-
"test-spec": inventory.testSpecs
|
|
61
|
-
}[specType];
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Analyze contract integrity.
|
|
65
|
-
*/
|
|
66
|
-
async function analyzeIntegrity(adapters, options = {}) {
|
|
67
|
-
const { fs, logger } = adapters;
|
|
68
|
-
logger.info("Starting integrity analysis...", { options });
|
|
69
|
-
const files = await fs.glob({ pattern: options.pattern });
|
|
70
|
-
const inventory = createEmptyInventory();
|
|
71
|
-
const features = [];
|
|
72
|
-
const issues = [];
|
|
73
|
-
for (const file of files) {
|
|
74
|
-
const content = await fs.readFile(file);
|
|
75
|
-
if (isFeatureFile(file)) {
|
|
76
|
-
const feature = scanFeatureSource(content, file);
|
|
77
|
-
features.push(feature);
|
|
78
|
-
} else {
|
|
79
|
-
const specs = scanAllSpecsFromSource(content, file);
|
|
80
|
-
for (const spec of specs) if (spec.specType !== "unknown" && spec.specType !== "feature") {
|
|
81
|
-
const map = getInventoryMap(inventory, spec.specType);
|
|
82
|
-
if (map && spec.name && spec.version !== void 0) {
|
|
83
|
-
const key = specKey(spec.name, spec.version);
|
|
84
|
-
map.set(key, {
|
|
85
|
-
name: spec.name,
|
|
86
|
-
version: spec.version,
|
|
87
|
-
file: spec.filePath,
|
|
88
|
-
type: spec.specType,
|
|
89
|
-
stability: spec.stability
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
const relevantFeatures = options.featureKey ? features.filter((f) => f.key === options.featureKey) : features;
|
|
96
|
-
const referencedSpecs = /* @__PURE__ */ new Set();
|
|
97
|
-
for (const feature of relevantFeatures) {
|
|
98
|
-
for (const ref of feature.operations) {
|
|
99
|
-
const key = specKey(ref.name, ref.version);
|
|
100
|
-
referencedSpecs.add(`operation:${key}`);
|
|
101
|
-
if (!inventory.operations.has(key)) issues.push({
|
|
102
|
-
severity: "error",
|
|
103
|
-
type: "unresolved-ref",
|
|
104
|
-
message: `Operation ${ref.name}.v${ref.version} not found`,
|
|
105
|
-
file: feature.filePath,
|
|
106
|
-
featureKey: feature.key,
|
|
107
|
-
specType: "operation",
|
|
108
|
-
ref
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
for (const ref of feature.events) {
|
|
112
|
-
const key = specKey(ref.name, ref.version);
|
|
113
|
-
referencedSpecs.add(`event:${key}`);
|
|
114
|
-
if (!inventory.events.has(key)) issues.push({
|
|
115
|
-
severity: "error",
|
|
116
|
-
type: "unresolved-ref",
|
|
117
|
-
message: `Event ${ref.name}.v${ref.version} not found`,
|
|
118
|
-
file: feature.filePath,
|
|
119
|
-
featureKey: feature.key,
|
|
120
|
-
specType: "event",
|
|
121
|
-
ref
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
for (const ref of feature.presentations) {
|
|
125
|
-
const key = specKey(ref.name, ref.version);
|
|
126
|
-
referencedSpecs.add(`presentation:${key}`);
|
|
127
|
-
if (!inventory.presentations.has(key)) issues.push({
|
|
128
|
-
severity: "error",
|
|
129
|
-
type: "unresolved-ref",
|
|
130
|
-
message: `Presentation ${ref.name}.v${ref.version} not found`,
|
|
131
|
-
file: feature.filePath,
|
|
132
|
-
featureKey: feature.key,
|
|
133
|
-
specType: "presentation",
|
|
134
|
-
ref
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
for (const ref of feature.experiments) {
|
|
138
|
-
const key = specKey(ref.name, ref.version);
|
|
139
|
-
referencedSpecs.add(`experiment:${key}`);
|
|
140
|
-
if (!inventory.experiments.has(key)) issues.push({
|
|
141
|
-
severity: "error",
|
|
142
|
-
type: "unresolved-ref",
|
|
143
|
-
message: `Experiment ${ref.name}.v${ref.version} not found`,
|
|
144
|
-
file: feature.filePath,
|
|
145
|
-
featureKey: feature.key,
|
|
146
|
-
specType: "experiment",
|
|
147
|
-
ref
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
for (const ref of feature.capabilities.provides) {
|
|
151
|
-
const key = specKey(ref.name, ref.version);
|
|
152
|
-
referencedSpecs.add(`capability:${key}`);
|
|
153
|
-
if (!inventory.capabilities.has(key)) issues.push({
|
|
154
|
-
severity: "warning",
|
|
155
|
-
type: "unresolved-ref",
|
|
156
|
-
message: `Provided capability ${ref.name}.v${ref.version} not found`,
|
|
157
|
-
file: feature.filePath,
|
|
158
|
-
featureKey: feature.key,
|
|
159
|
-
specType: "capability",
|
|
160
|
-
ref
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
for (const ref of feature.capabilities.requires) {
|
|
164
|
-
const key = specKey(ref.name, ref.version);
|
|
165
|
-
referencedSpecs.add(`capability:${key}`);
|
|
166
|
-
}
|
|
167
|
-
for (const link of feature.opToPresentationLinks) {
|
|
168
|
-
const opKey = specKey(link.op.name, link.op.version);
|
|
169
|
-
const presKey = specKey(link.pres.name, link.pres.version);
|
|
170
|
-
if (!inventory.operations.has(opKey)) issues.push({
|
|
171
|
-
severity: "error",
|
|
172
|
-
type: "broken-link",
|
|
173
|
-
message: `Linked operation ${link.op.name}.v${link.op.version} not found`,
|
|
174
|
-
file: feature.filePath,
|
|
175
|
-
featureKey: feature.key,
|
|
176
|
-
specType: "operation",
|
|
177
|
-
ref: link.op
|
|
178
|
-
});
|
|
179
|
-
if (!inventory.presentations.has(presKey)) issues.push({
|
|
180
|
-
severity: "error",
|
|
181
|
-
type: "broken-link",
|
|
182
|
-
message: `Linked presentation ${link.pres.name}.v${link.pres.version} not found`,
|
|
183
|
-
file: feature.filePath,
|
|
184
|
-
featureKey: feature.key,
|
|
185
|
-
specType: "presentation",
|
|
186
|
-
ref: link.pres
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
const orphanedSpecs = [];
|
|
191
|
-
const typesThatCanBeOrphaned = [
|
|
192
|
-
"operation",
|
|
193
|
-
"event",
|
|
194
|
-
"presentation",
|
|
195
|
-
"experiment"
|
|
196
|
-
];
|
|
197
|
-
for (const type of typesThatCanBeOrphaned) {
|
|
198
|
-
const map = getInventoryMap(inventory, type);
|
|
199
|
-
if (!map) continue;
|
|
200
|
-
for (const [key, location] of map) if (!referencedSpecs.has(`${type}:${key}`)) {
|
|
201
|
-
orphanedSpecs.push(location);
|
|
202
|
-
issues.push({
|
|
203
|
-
severity: "warning",
|
|
204
|
-
type: "orphaned",
|
|
205
|
-
message: `${type} ${location.name}.v${location.version} is not linked to any feature`,
|
|
206
|
-
file: location.file,
|
|
207
|
-
specName: location.name,
|
|
208
|
-
specType: location.type
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
const coverageByType = {};
|
|
213
|
-
for (const type of typesThatCanBeOrphaned) {
|
|
214
|
-
const map = getInventoryMap(inventory, type);
|
|
215
|
-
if (!map) continue;
|
|
216
|
-
const total = map.size;
|
|
217
|
-
let covered = 0;
|
|
218
|
-
for (const key of map.keys()) if (referencedSpecs.has(`${type}:${key}`)) covered++;
|
|
219
|
-
coverageByType[type] = {
|
|
220
|
-
total,
|
|
221
|
-
covered,
|
|
222
|
-
orphaned: total - covered
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
const totalSpecs = Object.values(coverageByType).reduce((sum, c) => sum + c.total, 0);
|
|
226
|
-
const coveredSpecs = Object.values(coverageByType).reduce((sum, c) => sum + c.covered, 0);
|
|
227
|
-
const coverage = {
|
|
228
|
-
total: totalSpecs,
|
|
229
|
-
linkedToFeature: coveredSpecs,
|
|
230
|
-
orphaned: totalSpecs - coveredSpecs,
|
|
231
|
-
byType: coverageByType
|
|
232
|
-
};
|
|
233
|
-
const healthy = !issues.some((i) => i.severity === "error");
|
|
234
|
-
logger.info("Integrity analysis complete", {
|
|
235
|
-
features: features.length,
|
|
236
|
-
totalSpecs,
|
|
237
|
-
orphaned: orphanedSpecs.length,
|
|
238
|
-
issues: issues.length,
|
|
239
|
-
healthy
|
|
240
|
-
});
|
|
241
|
-
return {
|
|
242
|
-
inventory,
|
|
243
|
-
features: relevantFeatures,
|
|
244
|
-
coverage,
|
|
245
|
-
issues,
|
|
246
|
-
orphanedSpecs,
|
|
247
|
-
healthy
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Get all specs from inventory as a flat list.
|
|
252
|
-
*/
|
|
253
|
-
function getAllSpecs(inventory) {
|
|
254
|
-
const all = [];
|
|
255
|
-
for (const map of Object.values(inventory)) for (const spec of map.values()) all.push(spec);
|
|
256
|
-
return all;
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Filter issues by type.
|
|
260
|
-
*/
|
|
261
|
-
function filterIssuesByType(issues, type) {
|
|
262
|
-
return issues.filter((i) => i.type === type);
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Filter issues by severity.
|
|
266
|
-
*/
|
|
267
|
-
function filterIssuesBySeverity(issues, severity) {
|
|
268
|
-
return issues.filter((i) => i.severity === severity);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
//#endregion
|
|
272
|
-
export { analyzeIntegrity, filterIssuesBySeverity, filterIssuesByType, getAllSpecs };
|
|
1
|
+
import{isFeatureFile as e,scanAllSpecsFromSource as t,scanFeatureSource as n}from"@lssm/module.contractspec-workspace";function r(e,t){return`${e}.v${t}`}function i(){return{operations:new Map,events:new Map,presentations:new Map,capabilities:new Map,workflows:new Map,dataViews:new Map,forms:new Map,migrations:new Map,experiments:new Map,integrations:new Map,knowledge:new Map,telemetry:new Map,appConfigs:new Map,policies:new Map,testSpecs:new Map}}function a(e,t){return{operation:e.operations,event:e.events,presentation:e.presentations,capability:e.capabilities,workflow:e.workflows,"data-view":e.dataViews,form:e.forms,migration:e.migrations,experiment:e.experiments,integration:e.integrations,knowledge:e.knowledge,telemetry:e.telemetry,"app-config":e.appConfigs,policy:e.policies,"test-spec":e.testSpecs}[t]}async function o(o,s={}){let{fs:c,logger:l}=o;l.info(`Starting integrity analysis...`,{options:s});let u=await c.glob({pattern:s.pattern}),d=i(),f=[],p=[];for(let i of u){let o=await c.readFile(i);if(e(i)){let e=n(o,i);f.push(e)}else{let e=t(o,i);for(let t of e)if(t.specType!==`unknown`&&t.specType!==`feature`){let e=a(d,t.specType);if(e&&t.name&&t.version!==void 0){let n=r(t.name,t.version);e.set(n,{name:t.name,version:t.version,file:t.filePath,type:t.specType,stability:t.stability})}}}}let m=s.featureKey?f.filter(e=>e.key===s.featureKey):f,h=new Set;for(let e of m){for(let t of e.operations){let n=r(t.name,t.version);h.add(`operation:${n}`),d.operations.has(n)||p.push({severity:`error`,type:`unresolved-ref`,message:`Operation ${t.name}.v${t.version} not found`,file:e.filePath,featureKey:e.key,specType:`operation`,ref:t})}for(let t of e.events){let n=r(t.name,t.version);h.add(`event:${n}`),d.events.has(n)||p.push({severity:`error`,type:`unresolved-ref`,message:`Event ${t.name}.v${t.version} not found`,file:e.filePath,featureKey:e.key,specType:`event`,ref:t})}for(let t of e.presentations){let n=r(t.name,t.version);h.add(`presentation:${n}`),d.presentations.has(n)||p.push({severity:`error`,type:`unresolved-ref`,message:`Presentation ${t.name}.v${t.version} not found`,file:e.filePath,featureKey:e.key,specType:`presentation`,ref:t})}for(let t of e.experiments){let n=r(t.name,t.version);h.add(`experiment:${n}`),d.experiments.has(n)||p.push({severity:`error`,type:`unresolved-ref`,message:`Experiment ${t.name}.v${t.version} not found`,file:e.filePath,featureKey:e.key,specType:`experiment`,ref:t})}for(let t of e.capabilities.provides){let n=r(t.name,t.version);h.add(`capability:${n}`),d.capabilities.has(n)||p.push({severity:`warning`,type:`unresolved-ref`,message:`Provided capability ${t.name}.v${t.version} not found`,file:e.filePath,featureKey:e.key,specType:`capability`,ref:t})}for(let t of e.capabilities.requires){let e=r(t.name,t.version);h.add(`capability:${e}`)}for(let t of e.opToPresentationLinks){let n=r(t.op.name,t.op.version),i=r(t.pres.name,t.pres.version);d.operations.has(n)||p.push({severity:`error`,type:`broken-link`,message:`Linked operation ${t.op.name}.v${t.op.version} not found`,file:e.filePath,featureKey:e.key,specType:`operation`,ref:t.op}),d.presentations.has(i)||p.push({severity:`error`,type:`broken-link`,message:`Linked presentation ${t.pres.name}.v${t.pres.version} not found`,file:e.filePath,featureKey:e.key,specType:`presentation`,ref:t.pres})}}let g=[],_=[`operation`,`event`,`presentation`,`experiment`];for(let e of _){let t=a(d,e);if(t)for(let[n,r]of t)h.has(`${e}:${n}`)||(g.push(r),p.push({severity:`warning`,type:`orphaned`,message:`${e} ${r.name}.v${r.version} is not linked to any feature`,file:r.file,specName:r.name,specType:r.type}))}let v={};for(let e of _){let t=a(d,e);if(!t)continue;let n=t.size,r=0;for(let n of t.keys())h.has(`${e}:${n}`)&&r++;v[e]={total:n,covered:r,orphaned:n-r}}let y=Object.values(v).reduce((e,t)=>e+t.total,0),b=Object.values(v).reduce((e,t)=>e+t.covered,0),x={total:y,linkedToFeature:b,orphaned:y-b,byType:v},S=!p.some(e=>e.severity===`error`);return l.info(`Integrity analysis complete`,{features:f.length,totalSpecs:y,orphaned:g.length,issues:p.length,healthy:S}),{inventory:d,features:m,coverage:x,issues:p,orphanedSpecs:g,healthy:S}}function s(e){let t=[];for(let n of Object.values(e))for(let e of n.values())t.push(e);return t}function c(e,t){return e.filter(e=>e.type===t)}function l(e,t){return e.filter(e=>e.severity===t)}export{o as analyzeIntegrity,l as filterIssuesBySeverity,c as filterIssuesByType,s as getAllSpecs};
|
package/dist/services/list.js
CHANGED
|
@@ -1,35 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
//#region src/services/list.ts
|
|
4
|
-
/**
|
|
5
|
-
* List specs service.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* List all spec files in the workspace.
|
|
9
|
-
*/
|
|
10
|
-
async function listSpecs(adapters, options = {}) {
|
|
11
|
-
const { fs } = adapters;
|
|
12
|
-
const files = await fs.glob({ pattern: options.pattern });
|
|
13
|
-
const results = [];
|
|
14
|
-
for (const file of files) {
|
|
15
|
-
const result = scanSpecSource(await fs.readFile(file), file);
|
|
16
|
-
if (options.type && result.specType !== options.type) continue;
|
|
17
|
-
results.push(result);
|
|
18
|
-
}
|
|
19
|
-
return results;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Group specs by type.
|
|
23
|
-
*/
|
|
24
|
-
function groupSpecsByType(specs) {
|
|
25
|
-
const groups = /* @__PURE__ */ new Map();
|
|
26
|
-
for (const spec of specs) {
|
|
27
|
-
const group = groups.get(spec.specType) ?? [];
|
|
28
|
-
group.push(spec);
|
|
29
|
-
groups.set(spec.specType, group);
|
|
30
|
-
}
|
|
31
|
-
return groups;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
//#endregion
|
|
35
|
-
export { groupSpecsByType, listSpecs };
|
|
1
|
+
import{scanSpecSource as e}from"@lssm/module.contractspec-workspace";async function t(t,n={}){let{fs:r}=t,i=await r.glob({pattern:n.pattern}),a=[];for(let t of i){let i=e(await r.readFile(t),t);n.type&&i.specType!==n.type||a.push(i)}return a}function n(e){let t=new Map;for(let n of e){let e=t.get(n.specType)??[];e.push(n),t.set(n.specType,e)}return t}export{n as groupSpecsByType,t as listSpecs};
|
|
@@ -1,51 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import "../../libs/contracts/dist/index.js";
|
|
4
|
-
|
|
5
|
-
//#region src/services/openapi/export-service.ts
|
|
6
|
-
/**
|
|
7
|
-
* OpenAPI export service - generates OpenAPI documents from SpecRegistry.
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Export OpenAPI document from a SpecRegistry.
|
|
11
|
-
*/
|
|
12
|
-
async function exportOpenApi(options, adapters) {
|
|
13
|
-
const { fs, logger } = adapters;
|
|
14
|
-
const { registryPath, outputPath = "./openapi.json" } = options;
|
|
15
|
-
logger.info("Loading registry...", { registryPath });
|
|
16
|
-
const registry = await loadRegistry(registryPath, fs);
|
|
17
|
-
logger.info("Generating OpenAPI document...");
|
|
18
|
-
const document = openApiForRegistry(registry, {
|
|
19
|
-
title: options.title,
|
|
20
|
-
version: options.version,
|
|
21
|
-
description: options.description,
|
|
22
|
-
servers: options.servers
|
|
23
|
-
});
|
|
24
|
-
const json = JSON.stringify(document, null, 2) + "\n";
|
|
25
|
-
const resolvedPath = fs.resolve(outputPath);
|
|
26
|
-
await fs.mkdir(fs.dirname(resolvedPath));
|
|
27
|
-
await fs.writeFile(resolvedPath, json);
|
|
28
|
-
logger.info(`OpenAPI document written to ${resolvedPath}`);
|
|
29
|
-
return {
|
|
30
|
-
document,
|
|
31
|
-
outputPath: resolvedPath,
|
|
32
|
-
json
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Load a SpecRegistry from a module.
|
|
37
|
-
*/
|
|
38
|
-
async function loadRegistry(modulePath, fs) {
|
|
39
|
-
const exports = await import(fs.resolve(modulePath));
|
|
40
|
-
if (exports instanceof SpecRegistry) return exports;
|
|
41
|
-
if (exports.registry instanceof SpecRegistry) return exports.registry;
|
|
42
|
-
const factory = typeof exports.createRegistry === "function" ? exports.createRegistry : typeof exports.default === "function" ? exports.default : void 0;
|
|
43
|
-
if (factory) {
|
|
44
|
-
const result = await factory();
|
|
45
|
-
if (result instanceof SpecRegistry) return result;
|
|
46
|
-
}
|
|
47
|
-
throw new Error(`Registry module ${modulePath} must export a SpecRegistry instance or a factory function returning one.`);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
//#endregion
|
|
51
|
-
export { exportOpenApi };
|
|
1
|
+
import{SpecRegistry as e,openApiForRegistry as t}from"@lssm/lib.contracts";async function n(e,n){let{fs:i,logger:a}=n,{registryPath:o,outputPath:s=`./openapi.json`}=e;a.info(`Loading registry...`,{registryPath:o});let c=await r(o,i);a.info(`Generating OpenAPI document...`);let l=t(c,{title:e.title,version:e.version,description:e.description,servers:e.servers}),u=JSON.stringify(l,null,2)+`
|
|
2
|
+
`,d=i.resolve(s);return await i.mkdir(i.dirname(d)),await i.writeFile(d,u),a.info(`OpenAPI document written to ${d}`),{document:l,outputPath:d,json:u}}async function r(t,n){let r=await import(n.resolve(t));if(r instanceof e)return r;if(r.registry instanceof e)return r.registry;let i=typeof r.createRegistry==`function`?r.createRegistry:typeof r.default==`function`?r.default:void 0;if(i){let t=await i();if(t instanceof e)return t}throw Error(`Registry module ${t} must export a SpecRegistry instance or a factory function returning one.`)}export{n as exportOpenApi};
|