@contractspec/bundle.library 3.8.10 → 3.8.12
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/.turbo/turbo-build.log +606 -594
- package/CHANGELOG.md +59 -0
- package/dist/application/context-storage/index.js +1 -28
- package/dist/application/index.js +13 -2133
- package/dist/application/mcp/cliMcp.js +4 -452
- package/dist/application/mcp/common.js +1 -193
- package/dist/application/mcp/contractsMcp.js +2 -549
- package/dist/application/mcp/contractsMcpResources.js +2 -123
- package/dist/application/mcp/contractsMcpTools.js +1 -199
- package/dist/application/mcp/docsMcp.catalog.js +3 -381
- package/dist/application/mcp/docsMcp.data.js +1 -147
- package/dist/application/mcp/docsMcp.js +6 -1039
- package/dist/application/mcp/docsMcp.prompts.js +6 -521
- package/dist/application/mcp/docsMcp.reference.js +3 -235
- package/dist/application/mcp/docsMcp.resources.js +3 -519
- package/dist/application/mcp/docsMcp.tools.js +3 -518
- package/dist/application/mcp/index.js +13 -2106
- package/dist/application/mcp/internalMcp.js +2 -410
- package/dist/application/mcp/normalizeMcpRequest.js +1 -21
- package/dist/application/mcp/providerRankingMcp.js +1 -530
- package/dist/bundles/LibraryBundle.js +1 -138
- package/dist/bundles/index.js +1 -138
- package/dist/components/docs/DocsIndexPage.js +2 -912
- package/dist/components/docs/advanced/AdvancedMCPPage.js +4 -271
- package/dist/components/docs/advanced/AdvancedOverlayEditorPage.js +1 -107
- package/dist/components/docs/advanced/AdvancedRenderersPage.js +2 -118
- package/dist/components/docs/advanced/AdvancedSpecExperimentsPage.js +4 -92
- package/dist/components/docs/advanced/AdvancedTelemetryPage.js +2 -373
- package/dist/components/docs/advanced/AdvancedWorkflowMonitoringPage.js +2 -99
- package/dist/components/docs/advanced/index.js +10 -1055
- package/dist/components/docs/architecture/ArchitectureAppConfigPage.js +6 -243
- package/dist/components/docs/architecture/ArchitectureControlPlanePage.js +3 -160
- package/dist/components/docs/architecture/ArchitectureIntegrationBindingPage.js +7 -259
- package/dist/components/docs/architecture/ArchitectureKnowledgeBindingPage.js +6 -374
- package/dist/components/docs/architecture/ArchitectureMultiTenancyPage.js +2 -166
- package/dist/components/docs/architecture/ArchitectureOverviewPage.js +1 -143
- package/dist/components/docs/architecture/index.js +20 -1340
- package/dist/components/docs/comparison/ComparisonAutomationPlatformsPage.js +1 -245
- package/dist/components/docs/comparison/ComparisonEnterprisePlatformsPage.js +1 -230
- package/dist/components/docs/comparison/ComparisonInternalToolBuildersPage.js +1 -245
- package/dist/components/docs/comparison/ComparisonOverviewPage.js +1 -202
- package/dist/components/docs/comparison/ComparisonWindmillPage.js +1 -254
- package/dist/components/docs/comparison/ComparisonWorkflowEnginesPage.js +1 -339
- package/dist/components/docs/comparison/index.js +1 -1510
- package/dist/components/docs/docsManifest.js +1 -611
- package/dist/components/docs/docsManifest.test.d.ts +1 -0
- package/dist/components/docs/ecosystem/IntegrationsPage.js +2 -103
- package/dist/components/docs/ecosystem/PluginsPage.js +13 -179
- package/dist/components/docs/ecosystem/RegistryPage.js +7 -100
- package/dist/components/docs/ecosystem/TemplatesPage.js +3 -141
- package/dist/components/docs/ecosystem/ecosystem.docblocks.js +2 -48
- package/dist/components/docs/ecosystem/index.js +23 -569
- package/dist/components/docs/examples/DocsExamplesPage.js +4 -124
- package/dist/components/docs/examples/ExampleShowcasePage.js +4 -244
- package/dist/components/docs/examples/exampleShowcaseData.js +4 -39
- package/dist/components/docs/examples/index.js +4 -330
- package/dist/components/docs/generated/docs-index.generated.js +1 -5
- package/dist/components/docs/generated/index.js +1 -74
- package/dist/components/docs/generated/loader.js +1 -74
- package/dist/components/docs/getting-started/CLIPage.js +4 -271
- package/dist/components/docs/getting-started/CompatibilityPage.js +1 -173
- package/dist/components/docs/getting-started/DataViewTutorialPage.js +4 -134
- package/dist/components/docs/getting-started/DeveloperToolsPage.js +1 -194
- package/dist/components/docs/getting-started/HelloWorldPage.js +5 -183
- package/dist/components/docs/getting-started/InstallationPage.js +3 -154
- package/dist/components/docs/getting-started/StartHerePage.js +2 -129
- package/dist/components/docs/getting-started/TroubleshootingPage.js +2 -168
- package/dist/components/docs/getting-started/VSCodeExtensionPage.js +1 -432
- package/dist/components/docs/getting-started/getting-started.docblocks.js +4 -41
- package/dist/components/docs/getting-started/index.js +18 -1869
- package/dist/components/docs/guides/GuideCIDiffGatingPage.js +2 -196
- package/dist/components/docs/guides/GuideConnectInRepoPage.d.ts +1 -0
- package/dist/components/docs/guides/GuideConnectInRepoPage.js +44 -0
- package/dist/components/docs/guides/GuideContractTypesPage.js +6 -541
- package/dist/components/docs/guides/GuideDocsPipelinePage.js +3 -207
- package/dist/components/docs/guides/GuideFirstModuleBundlePage.d.ts +1 -0
- package/dist/components/docs/guides/GuideFirstModuleBundlePage.js +76 -0
- package/dist/components/docs/guides/GuideGenerateDocsClientsSchemasPage.js +2 -209
- package/dist/components/docs/guides/GuideHostBuilderWorkbenchPage.d.ts +1 -0
- package/dist/components/docs/guides/GuideHostBuilderWorkbenchPage.js +70 -0
- package/dist/components/docs/guides/GuideImportExistingCodebasesPage.js +8 -754
- package/dist/components/docs/guides/GuideNextjsOneEndpointPage.js +6 -268
- package/dist/components/docs/guides/GuideSpecValidationTypingPage.js +4 -196
- package/dist/components/docs/guides/GuidesIndexPage.js +2 -169
- package/dist/components/docs/guides/guides.docblocks.js +11 -75
- package/dist/components/docs/guides/index.d.ts +3 -0
- package/dist/components/docs/guides/index.js +213 -2428
- package/dist/components/docs/index.js +542 -24310
- package/dist/components/docs/integrations/IntegrationsCircuitBreakersPage.js +2 -42
- package/dist/components/docs/integrations/IntegrationsElevenLabsPage.js +3 -105
- package/dist/components/docs/integrations/IntegrationsGithubPage.js +3 -142
- package/dist/components/docs/integrations/IntegrationsGmailPage.js +3 -109
- package/dist/components/docs/integrations/IntegrationsGoogleCalendarPage.js +3 -79
- package/dist/components/docs/integrations/IntegrationsHealthRoutingPage.js +3 -146
- package/dist/components/docs/integrations/IntegrationsMistralPage.js +5 -150
- package/dist/components/docs/integrations/IntegrationsOpenAIPage.js +5 -140
- package/dist/components/docs/integrations/IntegrationsOverviewPage.js +1 -160
- package/dist/components/docs/integrations/IntegrationsPostmarkPage.js +4 -218
- package/dist/components/docs/integrations/IntegrationsPowensPage.js +4 -300
- package/dist/components/docs/integrations/IntegrationsQdrantPage.js +5 -111
- package/dist/components/docs/integrations/IntegrationsResendPage.js +3 -102
- package/dist/components/docs/integrations/IntegrationsS3Page.js +4 -124
- package/dist/components/docs/integrations/IntegrationsSlackPage.js +3 -144
- package/dist/components/docs/integrations/IntegrationsSpecModelPage.js +7 -290
- package/dist/components/docs/integrations/IntegrationsStripePage.js +6 -327
- package/dist/components/docs/integrations/IntegrationsTwilioPage.js +3 -128
- package/dist/components/docs/integrations/IntegrationsWhatsappMetaPage.js +2 -146
- package/dist/components/docs/integrations/IntegrationsWhatsappTwilioPage.js +2 -156
- package/dist/components/docs/integrations/index.js +52 -3100
- package/dist/components/docs/intent/ContractFirstApiPage.js +2 -126
- package/dist/components/docs/intent/DeterministicCodegenPage.js +2 -148
- package/dist/components/docs/intent/GenerateClientFromSchemaPage.js +7 -207
- package/dist/components/docs/intent/OpenapiAlternativePage.js +3 -201
- package/dist/components/docs/intent/SchemaValidationTypescriptPage.js +4 -144
- package/dist/components/docs/intent/SpecDrivenDevelopmentPage.js +2 -126
- package/dist/components/docs/intent/index.js +15 -1135
- package/dist/components/docs/intent/intent-pages.docblocks.js +1 -201
- package/dist/components/docs/knowledge/KnowledgeCategoriesPage.js +6 -750
- package/dist/components/docs/knowledge/KnowledgeExamplesPage.js +4 -175
- package/dist/components/docs/knowledge/KnowledgeOverviewPage.js +1 -116
- package/dist/components/docs/knowledge/KnowledgeSourcesPage.js +8 -391
- package/dist/components/docs/knowledge/KnowledgeSpacesPage.js +6 -302
- package/dist/components/docs/knowledge/index.js +21 -1730
- package/dist/components/docs/libraries/LibrariesAccessibilityPage.js +3 -198
- package/dist/components/docs/libraries/LibrariesAiAgentPage.js +3 -141
- package/dist/components/docs/libraries/LibrariesAnalyticsPage.js +4 -80
- package/dist/components/docs/libraries/LibrariesContentGenPage.js +2 -100
- package/dist/components/docs/libraries/LibrariesContractsPage.js +2 -284
- package/dist/components/docs/libraries/LibrariesCostTrackingPage.js +3 -112
- package/dist/components/docs/libraries/LibrariesDataBackendPage.js +2 -166
- package/dist/components/docs/libraries/LibrariesDataViewsPage.js +3 -186
- package/dist/components/docs/libraries/LibrariesDesignSystemPage.js +4 -279
- package/dist/components/docs/libraries/LibrariesEvolutionPage.js +4 -127
- package/dist/components/docs/libraries/LibrariesGraphQLPage.js +2 -173
- package/dist/components/docs/libraries/LibrariesGrowthPage.js +3 -88
- package/dist/components/docs/libraries/LibrariesMultiTenancyPage.js +3 -108
- package/dist/components/docs/libraries/LibrariesObservabilityPage.js +5 -130
- package/dist/components/docs/libraries/LibrariesOverlayEnginePage.js +4 -110
- package/dist/components/docs/libraries/LibrariesOverviewPage.js +1 -170
- package/dist/components/docs/libraries/LibrariesPersonalizationPage.js +4 -114
- package/dist/components/docs/libraries/LibrariesProgressiveDeliveryPage.js +3 -132
- package/dist/components/docs/libraries/LibrariesResiliencePage.js +4 -120
- package/dist/components/docs/libraries/LibrariesRuntimePage.js +2 -200
- package/dist/components/docs/libraries/LibrariesSLOPage.js +3 -116
- package/dist/components/docs/libraries/LibrariesSchemaPage.js +3 -273
- package/dist/components/docs/libraries/LibrariesSupportBotPage.js +3 -134
- package/dist/components/docs/libraries/LibrariesTestingPage.js +3 -133
- package/dist/components/docs/libraries/LibrariesUIKitPage.js +2 -230
- package/dist/components/docs/libraries/LibrariesWorkflowComposerPage.js +3 -88
- package/dist/components/docs/libraries/LibrariesWorkflowsPage.js +2 -181
- package/dist/components/docs/libraries/index.js +54 -4147
- package/dist/components/docs/manifesto/ManifestoPage.js +1 -86
- package/dist/components/docs/ops/AutoEvolutionOpsPage.js +2 -132
- package/dist/components/docs/ops/DistributedTracingOpsPage.js +2 -71
- package/dist/components/docs/ops/index.js +3 -202
- package/dist/components/docs/ops/ops-lifecycle.docblocks.js +3 -38
- package/dist/components/docs/ops/ops-runbooks-a.docblocks.js +3 -94
- package/dist/components/docs/ops/ops-runbooks-b.docblocks.js +3 -76
- package/dist/components/docs/ops/ops-slo-tenant.docblocks.js +3 -76
- package/dist/components/docs/ops/ops-top.docs.js +2 -17
- package/dist/components/docs/ops/ops.docs.js +10 -302
- package/dist/components/docs/product/product.docblocks.js +5 -72
- package/dist/components/docs/reference/DocsMarkdownContent.js +2 -196
- package/dist/components/docs/reference/DocsReferenceContent.js +3 -256
- package/dist/components/docs/reference/DocsReferenceIndexClient.js +2 -127
- package/dist/components/docs/reference/DocsReferenceIndexPage.js +2 -206
- package/dist/components/docs/reference/DocsReferencePage.js +3 -265
- package/dist/components/docs/reference/docsMarkdownParser.js +2 -92
- package/dist/components/docs/reference/index.js +4 -470
- package/dist/components/docs/safety/SafetyAuditingPage.js +2 -350
- package/dist/components/docs/safety/SafetyMigrationsPage.js +2 -359
- package/dist/components/docs/safety/SafetyOverviewPage.js +1 -101
- package/dist/components/docs/safety/SafetyPDPPage.js +2 -301
- package/dist/components/docs/safety/SafetySecurityTrustPage.js +1 -206
- package/dist/components/docs/safety/SafetySigningPage.js +3 -90
- package/dist/components/docs/safety/SafetyTenantIsolationPage.js +2 -79
- package/dist/components/docs/safety/index.js +7 -1480
- package/dist/components/docs/shared/StudioPrompt.js +1 -31
- package/dist/components/docs/specs/SpecsBuilderControlPlanePage.d.ts +1 -0
- package/dist/components/docs/specs/SpecsBuilderControlPlanePage.js +34 -0
- package/dist/components/docs/specs/SpecsCapabilitiesPage.js +2 -158
- package/dist/components/docs/specs/SpecsConnectPage.d.ts +1 -0
- package/dist/components/docs/specs/SpecsConnectPage.js +8 -0
- package/dist/components/docs/specs/SpecsDataViewsPage.js +2 -260
- package/dist/components/docs/specs/SpecsModuleBundlesPage.d.ts +1 -0
- package/dist/components/docs/specs/SpecsModuleBundlesPage.js +67 -0
- package/dist/components/docs/specs/SpecsOverlaysPage.js +2 -372
- package/dist/components/docs/specs/SpecsOverviewPage.js +1 -186
- package/dist/components/docs/specs/SpecsPolicyPage.js +3 -420
- package/dist/components/docs/specs/SpecsWorkflowsPage.js +2 -325
- package/dist/components/docs/specs/index.d.ts +3 -0
- package/dist/components/docs/specs/index.js +109 -1715
- package/dist/components/docs/studio/StudioBYOKPage.js +1 -26
- package/dist/components/docs/studio/StudioDeploymentsPage.js +1 -26
- package/dist/components/docs/studio/StudioGettingStartedPage.js +1 -26
- package/dist/components/docs/studio/StudioIntegrationsPage.js +1 -26
- package/dist/components/docs/studio/StudioOverviewPage.js +1 -157
- package/dist/components/docs/studio/StudioVisualBuilderPage.js +1 -26
- package/dist/components/docs/studio/index.js +1 -282
- package/dist/components/docs/tech/contracts/tech-docs.docblocks.js +2 -19
- package/dist/components/integrations/index.js +2 -600
- package/dist/components/integrations/molecules/IntegrationCard.js +1 -100
- package/dist/components/integrations/organisms/IntegrationMarketplace.js +1 -214
- package/dist/components/integrations/organisms/IntegrationSettings.js +2 -284
- package/dist/components/integrations/organisms/KnowledgeSourceList.js +1 -103
- package/dist/components/legal/PrivacyTemplate.js +1 -1025
- package/dist/components/legal/TermsTemplate.js +1 -941
- package/dist/components/legal/index.js +1 -1963
- package/dist/components/shared/FeatureGateNotice.js +1 -38
- package/dist/components/shared/index.js +1 -38
- package/dist/components/shell/WorkspaceHeader.js +1 -100
- package/dist/components/shell/WorkspaceProjectShellLayout.js +1 -222
- package/dist/components/shell/WorkspaceShellRenderer.js +1 -228
- package/dist/components/shell/WorkspaceSidebar.js +1 -68
- package/dist/components/shell/index.js +1 -287
- package/dist/components/templates/engine/index.js +1 -39
- package/dist/components/templates/index.js +11 -965
- package/dist/components/templates/messaging/ConversationList.js +2 -83
- package/dist/components/templates/messaging/MessageComposer.js +4 -150
- package/dist/components/templates/messaging/MessageThread.js +3 -83
- package/dist/components/templates/messaging/MessagingWorkspace.js +5 -265
- package/dist/components/templates/messaging/index.js +5 -269
- package/dist/components/templates/recipes/LanguageSwitcher.js +1 -16
- package/dist/components/templates/recipes/RecipeCard.js +1 -80
- package/dist/components/templates/recipes/RecipeDetail.js +1 -74
- package/dist/components/templates/recipes/RecipeList.js +3 -245
- package/dist/components/templates/recipes/index.js +3 -248
- package/dist/components/templates/todos/FilterBar.js +1 -107
- package/dist/components/templates/todos/TaskForm.js +2 -158
- package/dist/components/templates/todos/TaskItem.js +1 -77
- package/dist/components/templates/todos/TaskList.js +5 -449
- package/dist/components/templates/todos/index.js +5 -452
- package/dist/config/contractspec-blueprint.js +1 -123
- package/dist/config/contractspec-branding.js +1 -44
- package/dist/config/contractspec-routes.js +1 -24
- package/dist/config/index.js +1 -126
- package/dist/features/contracts-registry.js +1 -178
- package/dist/features/docs/docs.contracts.js +1 -17
- package/dist/features/docs/index.js +1 -17
- package/dist/features/docs.feature.js +1 -33
- package/dist/features/index.js +1 -315
- package/dist/features/mcp.feature.js +1 -30
- package/dist/features/presentations.feature.js +1 -33
- package/dist/features/registry.js +1 -116
- package/dist/index.js +556 -28593
- package/dist/infrastructure/elysia/index.js +1 -35
- package/dist/infrastructure/elysia/logger.js +1 -35
- package/dist/infrastructure/index.js +1 -35
- package/dist/libs/email/client.js +1 -114
- package/dist/libs/email/contact.js +12 -165
- package/dist/libs/email/newsletter.js +6 -167
- package/dist/libs/email/types.js +0 -2
- package/dist/libs/email/utils.js +2 -8
- package/dist/libs/email/waitlist-application.js +28 -209
- package/dist/libs/email/waitlist.js +6 -167
- package/dist/libs/email.js +46 -363
- package/dist/libs/posthog/client.js +1 -63
- package/dist/libs/posthog/native.js +1 -23
- package/dist/libs/posthog/server.js +1 -13
- package/dist/libs/pricing-examples.js +1 -18
- package/dist/node/application/context-storage/index.js +1 -28
- package/dist/node/application/index.js +13 -2133
- package/dist/node/application/mcp/cliMcp.js +4 -452
- package/dist/node/application/mcp/common.js +1 -193
- package/dist/node/application/mcp/contractsMcp.js +2 -549
- package/dist/node/application/mcp/contractsMcpResources.js +2 -123
- package/dist/node/application/mcp/contractsMcpTools.js +1 -199
- package/dist/node/application/mcp/docsMcp.catalog.js +3 -381
- package/dist/node/application/mcp/docsMcp.data.js +1 -147
- package/dist/node/application/mcp/docsMcp.js +6 -1039
- package/dist/node/application/mcp/docsMcp.prompts.js +6 -521
- package/dist/node/application/mcp/docsMcp.reference.js +3 -235
- package/dist/node/application/mcp/docsMcp.resources.js +3 -519
- package/dist/node/application/mcp/docsMcp.tools.js +3 -518
- package/dist/node/application/mcp/index.js +13 -2106
- package/dist/node/application/mcp/internalMcp.js +2 -410
- package/dist/node/application/mcp/normalizeMcpRequest.js +1 -21
- package/dist/node/application/mcp/providerRankingMcp.js +1 -530
- package/dist/node/bundles/LibraryBundle.js +1 -138
- package/dist/node/bundles/index.js +1 -138
- package/dist/node/components/docs/DocsIndexPage.js +2 -912
- package/dist/node/components/docs/advanced/AdvancedMCPPage.js +4 -271
- package/dist/node/components/docs/advanced/AdvancedOverlayEditorPage.js +1 -107
- package/dist/node/components/docs/advanced/AdvancedRenderersPage.js +2 -118
- package/dist/node/components/docs/advanced/AdvancedSpecExperimentsPage.js +4 -92
- package/dist/node/components/docs/advanced/AdvancedTelemetryPage.js +2 -373
- package/dist/node/components/docs/advanced/AdvancedWorkflowMonitoringPage.js +2 -99
- package/dist/node/components/docs/advanced/index.js +10 -1055
- package/dist/node/components/docs/architecture/ArchitectureAppConfigPage.js +6 -243
- package/dist/node/components/docs/architecture/ArchitectureControlPlanePage.js +3 -160
- package/dist/node/components/docs/architecture/ArchitectureIntegrationBindingPage.js +7 -259
- package/dist/node/components/docs/architecture/ArchitectureKnowledgeBindingPage.js +6 -374
- package/dist/node/components/docs/architecture/ArchitectureMultiTenancyPage.js +2 -166
- package/dist/node/components/docs/architecture/ArchitectureOverviewPage.js +1 -143
- package/dist/node/components/docs/architecture/index.js +20 -1340
- package/dist/node/components/docs/comparison/ComparisonAutomationPlatformsPage.js +1 -245
- package/dist/node/components/docs/comparison/ComparisonEnterprisePlatformsPage.js +1 -230
- package/dist/node/components/docs/comparison/ComparisonInternalToolBuildersPage.js +1 -245
- package/dist/node/components/docs/comparison/ComparisonOverviewPage.js +1 -202
- package/dist/node/components/docs/comparison/ComparisonWindmillPage.js +1 -254
- package/dist/node/components/docs/comparison/ComparisonWorkflowEnginesPage.js +1 -339
- package/dist/node/components/docs/comparison/index.js +1 -1510
- package/dist/node/components/docs/docsManifest.js +1 -611
- package/dist/node/components/docs/ecosystem/IntegrationsPage.js +2 -103
- package/dist/node/components/docs/ecosystem/PluginsPage.js +13 -179
- package/dist/node/components/docs/ecosystem/RegistryPage.js +7 -100
- package/dist/node/components/docs/ecosystem/TemplatesPage.js +3 -141
- package/dist/node/components/docs/ecosystem/ecosystem.docblocks.js +2 -48
- package/dist/node/components/docs/ecosystem/index.js +23 -569
- package/dist/node/components/docs/examples/DocsExamplesPage.js +4 -124
- package/dist/node/components/docs/examples/ExampleShowcasePage.js +4 -244
- package/dist/node/components/docs/examples/exampleShowcaseData.js +4 -39
- package/dist/node/components/docs/examples/index.js +4 -330
- package/dist/node/components/docs/generated/docs-index.generated.js +1 -5
- package/dist/node/components/docs/generated/index.js +1 -74
- package/dist/node/components/docs/generated/loader.js +1 -74
- package/dist/node/components/docs/getting-started/CLIPage.js +4 -271
- package/dist/node/components/docs/getting-started/CompatibilityPage.js +1 -173
- package/dist/node/components/docs/getting-started/DataViewTutorialPage.js +4 -134
- package/dist/node/components/docs/getting-started/DeveloperToolsPage.js +1 -194
- package/dist/node/components/docs/getting-started/HelloWorldPage.js +5 -183
- package/dist/node/components/docs/getting-started/InstallationPage.js +3 -154
- package/dist/node/components/docs/getting-started/StartHerePage.js +2 -129
- package/dist/node/components/docs/getting-started/TroubleshootingPage.js +2 -168
- package/dist/node/components/docs/getting-started/VSCodeExtensionPage.js +1 -432
- package/dist/node/components/docs/getting-started/getting-started.docblocks.js +4 -41
- package/dist/node/components/docs/getting-started/index.js +18 -1869
- package/dist/node/components/docs/guides/GuideCIDiffGatingPage.js +2 -196
- package/dist/node/components/docs/guides/GuideConnectInRepoPage.js +43 -0
- package/dist/node/components/docs/guides/GuideContractTypesPage.js +6 -541
- package/dist/node/components/docs/guides/GuideDocsPipelinePage.js +3 -207
- package/dist/node/components/docs/guides/GuideFirstModuleBundlePage.js +75 -0
- package/dist/node/components/docs/guides/GuideGenerateDocsClientsSchemasPage.js +2 -209
- package/dist/node/components/docs/guides/GuideHostBuilderWorkbenchPage.js +69 -0
- package/dist/node/components/docs/guides/GuideImportExistingCodebasesPage.js +8 -754
- package/dist/node/components/docs/guides/GuideNextjsOneEndpointPage.js +6 -268
- package/dist/node/components/docs/guides/GuideSpecValidationTypingPage.js +4 -196
- package/dist/node/components/docs/guides/GuidesIndexPage.js +2 -169
- package/dist/node/components/docs/guides/guides.docblocks.js +11 -75
- package/dist/node/components/docs/guides/index.js +213 -2428
- package/dist/node/components/docs/index.js +542 -24310
- package/dist/node/components/docs/integrations/IntegrationsCircuitBreakersPage.js +2 -42
- package/dist/node/components/docs/integrations/IntegrationsElevenLabsPage.js +3 -105
- package/dist/node/components/docs/integrations/IntegrationsGithubPage.js +3 -142
- package/dist/node/components/docs/integrations/IntegrationsGmailPage.js +3 -109
- package/dist/node/components/docs/integrations/IntegrationsGoogleCalendarPage.js +3 -79
- package/dist/node/components/docs/integrations/IntegrationsHealthRoutingPage.js +3 -146
- package/dist/node/components/docs/integrations/IntegrationsMistralPage.js +5 -150
- package/dist/node/components/docs/integrations/IntegrationsOpenAIPage.js +5 -140
- package/dist/node/components/docs/integrations/IntegrationsOverviewPage.js +1 -160
- package/dist/node/components/docs/integrations/IntegrationsPostmarkPage.js +4 -218
- package/dist/node/components/docs/integrations/IntegrationsPowensPage.js +4 -300
- package/dist/node/components/docs/integrations/IntegrationsQdrantPage.js +5 -111
- package/dist/node/components/docs/integrations/IntegrationsResendPage.js +3 -102
- package/dist/node/components/docs/integrations/IntegrationsS3Page.js +4 -124
- package/dist/node/components/docs/integrations/IntegrationsSlackPage.js +3 -144
- package/dist/node/components/docs/integrations/IntegrationsSpecModelPage.js +7 -290
- package/dist/node/components/docs/integrations/IntegrationsStripePage.js +6 -327
- package/dist/node/components/docs/integrations/IntegrationsTwilioPage.js +3 -128
- package/dist/node/components/docs/integrations/IntegrationsWhatsappMetaPage.js +2 -146
- package/dist/node/components/docs/integrations/IntegrationsWhatsappTwilioPage.js +2 -156
- package/dist/node/components/docs/integrations/index.js +52 -3100
- package/dist/node/components/docs/intent/ContractFirstApiPage.js +2 -126
- package/dist/node/components/docs/intent/DeterministicCodegenPage.js +2 -148
- package/dist/node/components/docs/intent/GenerateClientFromSchemaPage.js +7 -207
- package/dist/node/components/docs/intent/OpenapiAlternativePage.js +3 -201
- package/dist/node/components/docs/intent/SchemaValidationTypescriptPage.js +4 -144
- package/dist/node/components/docs/intent/SpecDrivenDevelopmentPage.js +2 -126
- package/dist/node/components/docs/intent/index.js +15 -1135
- package/dist/node/components/docs/intent/intent-pages.docblocks.js +1 -201
- package/dist/node/components/docs/knowledge/KnowledgeCategoriesPage.js +6 -750
- package/dist/node/components/docs/knowledge/KnowledgeExamplesPage.js +4 -175
- package/dist/node/components/docs/knowledge/KnowledgeOverviewPage.js +1 -116
- package/dist/node/components/docs/knowledge/KnowledgeSourcesPage.js +8 -391
- package/dist/node/components/docs/knowledge/KnowledgeSpacesPage.js +6 -302
- package/dist/node/components/docs/knowledge/index.js +21 -1730
- package/dist/node/components/docs/libraries/LibrariesAccessibilityPage.js +3 -198
- package/dist/node/components/docs/libraries/LibrariesAiAgentPage.js +3 -141
- package/dist/node/components/docs/libraries/LibrariesAnalyticsPage.js +4 -80
- package/dist/node/components/docs/libraries/LibrariesContentGenPage.js +2 -100
- package/dist/node/components/docs/libraries/LibrariesContractsPage.js +2 -284
- package/dist/node/components/docs/libraries/LibrariesCostTrackingPage.js +3 -112
- package/dist/node/components/docs/libraries/LibrariesDataBackendPage.js +2 -166
- package/dist/node/components/docs/libraries/LibrariesDataViewsPage.js +3 -186
- package/dist/node/components/docs/libraries/LibrariesDesignSystemPage.js +4 -279
- package/dist/node/components/docs/libraries/LibrariesEvolutionPage.js +4 -127
- package/dist/node/components/docs/libraries/LibrariesGraphQLPage.js +2 -173
- package/dist/node/components/docs/libraries/LibrariesGrowthPage.js +3 -88
- package/dist/node/components/docs/libraries/LibrariesMultiTenancyPage.js +3 -108
- package/dist/node/components/docs/libraries/LibrariesObservabilityPage.js +5 -130
- package/dist/node/components/docs/libraries/LibrariesOverlayEnginePage.js +4 -110
- package/dist/node/components/docs/libraries/LibrariesOverviewPage.js +1 -170
- package/dist/node/components/docs/libraries/LibrariesPersonalizationPage.js +4 -114
- package/dist/node/components/docs/libraries/LibrariesProgressiveDeliveryPage.js +3 -132
- package/dist/node/components/docs/libraries/LibrariesResiliencePage.js +4 -120
- package/dist/node/components/docs/libraries/LibrariesRuntimePage.js +2 -200
- package/dist/node/components/docs/libraries/LibrariesSLOPage.js +3 -116
- package/dist/node/components/docs/libraries/LibrariesSchemaPage.js +3 -273
- package/dist/node/components/docs/libraries/LibrariesSupportBotPage.js +3 -134
- package/dist/node/components/docs/libraries/LibrariesTestingPage.js +3 -133
- package/dist/node/components/docs/libraries/LibrariesUIKitPage.js +2 -230
- package/dist/node/components/docs/libraries/LibrariesWorkflowComposerPage.js +3 -88
- package/dist/node/components/docs/libraries/LibrariesWorkflowsPage.js +2 -181
- package/dist/node/components/docs/libraries/index.js +54 -4147
- package/dist/node/components/docs/manifesto/ManifestoPage.js +1 -86
- package/dist/node/components/docs/ops/AutoEvolutionOpsPage.js +2 -132
- package/dist/node/components/docs/ops/DistributedTracingOpsPage.js +2 -71
- package/dist/node/components/docs/ops/index.js +3 -202
- package/dist/node/components/docs/ops/ops-lifecycle.docblocks.js +3 -38
- package/dist/node/components/docs/ops/ops-runbooks-a.docblocks.js +3 -94
- package/dist/node/components/docs/ops/ops-runbooks-b.docblocks.js +3 -76
- package/dist/node/components/docs/ops/ops-slo-tenant.docblocks.js +3 -76
- package/dist/node/components/docs/ops/ops-top.docs.js +2 -17
- package/dist/node/components/docs/ops/ops.docs.js +10 -302
- package/dist/node/components/docs/product/product.docblocks.js +5 -72
- package/dist/node/components/docs/reference/DocsMarkdownContent.js +2 -196
- package/dist/node/components/docs/reference/DocsReferenceContent.js +3 -256
- package/dist/node/components/docs/reference/DocsReferenceIndexClient.js +2 -127
- package/dist/node/components/docs/reference/DocsReferenceIndexPage.js +2 -206
- package/dist/node/components/docs/reference/DocsReferencePage.js +3 -265
- package/dist/node/components/docs/reference/docsMarkdownParser.js +2 -92
- package/dist/node/components/docs/reference/index.js +4 -470
- package/dist/node/components/docs/safety/SafetyAuditingPage.js +2 -350
- package/dist/node/components/docs/safety/SafetyMigrationsPage.js +2 -359
- package/dist/node/components/docs/safety/SafetyOverviewPage.js +1 -101
- package/dist/node/components/docs/safety/SafetyPDPPage.js +2 -301
- package/dist/node/components/docs/safety/SafetySecurityTrustPage.js +1 -206
- package/dist/node/components/docs/safety/SafetySigningPage.js +3 -90
- package/dist/node/components/docs/safety/SafetyTenantIsolationPage.js +2 -79
- package/dist/node/components/docs/safety/index.js +7 -1480
- package/dist/node/components/docs/shared/StudioPrompt.js +1 -31
- package/dist/node/components/docs/specs/SpecsBuilderControlPlanePage.js +33 -0
- package/dist/node/components/docs/specs/SpecsCapabilitiesPage.js +2 -158
- package/dist/node/components/docs/specs/SpecsConnectPage.js +7 -0
- package/dist/node/components/docs/specs/SpecsDataViewsPage.js +2 -260
- package/dist/node/components/docs/specs/SpecsModuleBundlesPage.js +66 -0
- package/dist/node/components/docs/specs/SpecsOverlaysPage.js +2 -372
- package/dist/node/components/docs/specs/SpecsOverviewPage.js +1 -186
- package/dist/node/components/docs/specs/SpecsPolicyPage.js +3 -420
- package/dist/node/components/docs/specs/SpecsWorkflowsPage.js +2 -325
- package/dist/node/components/docs/specs/index.js +109 -1715
- package/dist/node/components/docs/studio/StudioBYOKPage.js +1 -26
- package/dist/node/components/docs/studio/StudioDeploymentsPage.js +1 -26
- package/dist/node/components/docs/studio/StudioGettingStartedPage.js +1 -26
- package/dist/node/components/docs/studio/StudioIntegrationsPage.js +1 -26
- package/dist/node/components/docs/studio/StudioOverviewPage.js +1 -157
- package/dist/node/components/docs/studio/StudioVisualBuilderPage.js +1 -26
- package/dist/node/components/docs/studio/index.js +1 -282
- package/dist/node/components/docs/tech/contracts/tech-docs.docblocks.js +2 -19
- package/dist/node/components/integrations/index.js +2 -600
- package/dist/node/components/integrations/molecules/IntegrationCard.js +1 -100
- package/dist/node/components/integrations/organisms/IntegrationMarketplace.js +1 -214
- package/dist/node/components/integrations/organisms/IntegrationSettings.js +2 -284
- package/dist/node/components/integrations/organisms/KnowledgeSourceList.js +1 -103
- package/dist/node/components/legal/PrivacyTemplate.js +1 -1025
- package/dist/node/components/legal/TermsTemplate.js +1 -941
- package/dist/node/components/legal/index.js +1 -1963
- package/dist/node/components/shared/FeatureGateNotice.js +1 -38
- package/dist/node/components/shared/index.js +1 -38
- package/dist/node/components/shell/WorkspaceHeader.js +1 -100
- package/dist/node/components/shell/WorkspaceProjectShellLayout.js +1 -222
- package/dist/node/components/shell/WorkspaceShellRenderer.js +1 -228
- package/dist/node/components/shell/WorkspaceSidebar.js +1 -68
- package/dist/node/components/shell/index.js +1 -287
- package/dist/node/components/templates/engine/index.js +1 -39
- package/dist/node/components/templates/index.js +11 -965
- package/dist/node/components/templates/messaging/ConversationList.js +2 -83
- package/dist/node/components/templates/messaging/MessageComposer.js +4 -150
- package/dist/node/components/templates/messaging/MessageThread.js +3 -83
- package/dist/node/components/templates/messaging/MessagingWorkspace.js +5 -265
- package/dist/node/components/templates/messaging/index.js +5 -269
- package/dist/node/components/templates/recipes/LanguageSwitcher.js +1 -16
- package/dist/node/components/templates/recipes/RecipeCard.js +1 -80
- package/dist/node/components/templates/recipes/RecipeDetail.js +1 -74
- package/dist/node/components/templates/recipes/RecipeList.js +3 -245
- package/dist/node/components/templates/recipes/index.js +3 -248
- package/dist/node/components/templates/todos/FilterBar.js +1 -107
- package/dist/node/components/templates/todos/TaskForm.js +2 -158
- package/dist/node/components/templates/todos/TaskItem.js +1 -77
- package/dist/node/components/templates/todos/TaskList.js +5 -449
- package/dist/node/components/templates/todos/index.js +5 -452
- package/dist/node/config/contractspec-blueprint.js +1 -123
- package/dist/node/config/contractspec-branding.js +1 -44
- package/dist/node/config/contractspec-routes.js +1 -24
- package/dist/node/config/index.js +1 -126
- package/dist/node/features/contracts-registry.js +1 -178
- package/dist/node/features/docs/docs.contracts.js +1 -17
- package/dist/node/features/docs/index.js +1 -17
- package/dist/node/features/docs.feature.js +1 -33
- package/dist/node/features/index.js +1 -315
- package/dist/node/features/mcp.feature.js +1 -30
- package/dist/node/features/presentations.feature.js +1 -33
- package/dist/node/features/registry.js +1 -116
- package/dist/node/index.js +556 -28593
- package/dist/node/infrastructure/elysia/index.js +1 -35
- package/dist/node/infrastructure/elysia/logger.js +1 -35
- package/dist/node/infrastructure/index.js +1 -35
- package/dist/node/libs/email/client.js +1 -114
- package/dist/node/libs/email/contact.js +12 -165
- package/dist/node/libs/email/newsletter.js +6 -167
- package/dist/node/libs/email/types.js +0 -2
- package/dist/node/libs/email/utils.js +2 -8
- package/dist/node/libs/email/waitlist-application.js +28 -209
- package/dist/node/libs/email/waitlist.js +6 -167
- package/dist/node/libs/email.js +46 -363
- package/dist/node/libs/posthog/client.js +1 -63
- package/dist/node/libs/posthog/native.js +1 -23
- package/dist/node/libs/posthog/server.js +1 -13
- package/dist/node/libs/pricing-examples.js +1 -18
- package/dist/node/presentation/features/atoms/FeatureIcon/FeatureIcon.js +1 -97
- package/dist/node/presentation/features/atoms/FeatureIcon/index.js +1 -97
- package/dist/node/presentation/features/atoms/index.js +1 -97
- package/dist/node/presentation/features/hooks/index.js +1 -397
- package/dist/node/presentation/features/hooks/useContractsRegistry.js +1 -289
- package/dist/node/presentation/features/hooks/useFeatureFilters.js +1 -75
- package/dist/node/presentation/features/hooks/useFeatureRegistry.js +1 -147
- package/dist/node/presentation/features/hooks/useRelatedDocs.js +1 -28
- package/dist/node/presentation/features/index.js +1 -3063
- package/dist/node/presentation/features/molecules/FeatureCard/FeatureCard.js +1 -366
- package/dist/node/presentation/features/molecules/FeatureCard/index.js +1 -366
- package/dist/node/presentation/features/molecules/FeatureCategoryHeader/FeatureCategoryHeader.js +1 -50
- package/dist/node/presentation/features/molecules/FeatureCategoryHeader/index.js +1 -50
- package/dist/node/presentation/features/molecules/FeatureFilters/FeatureFilters.js +1 -92
- package/dist/node/presentation/features/molecules/FeatureFilters/index.js +1 -92
- package/dist/node/presentation/features/molecules/FeatureHoverPreview/FeatureHoverPreview.js +1 -176
- package/dist/node/presentation/features/molecules/FeatureHoverPreview/index.js +1 -176
- package/dist/node/presentation/features/molecules/index.js +1 -505
- package/dist/node/presentation/features/organisms/FeatureDataViewsList.js +1 -304
- package/dist/node/presentation/features/organisms/FeatureDetail/FeatureDetail.js +1 -154
- package/dist/node/presentation/features/organisms/FeatureDetail/index.js +1 -154
- package/dist/node/presentation/features/organisms/FeatureDiscovery/FeatureDiscovery.js +1 -909
- package/dist/node/presentation/features/organisms/FeatureDiscovery/index.js +1 -909
- package/dist/node/presentation/features/organisms/FeatureEventsList.js +1 -302
- package/dist/node/presentation/features/organisms/FeatureFormsList.js +1 -302
- package/dist/node/presentation/features/organisms/FeatureOperationsList.js +1 -180
- package/dist/node/presentation/features/organisms/FeaturePresentationsList.js +1 -304
- package/dist/node/presentation/features/organisms/index.js +1 -1359
- package/dist/node/presentation/features/templates/FeatureDataViewDetailTemplate/FeatureDataViewDetailTemplate.js +1 -332
- package/dist/node/presentation/features/templates/FeatureDataViewDetailTemplate/index.js +1 -332
- package/dist/node/presentation/features/templates/FeatureDataViewsTemplate/FeatureDataViewsTemplate.js +1 -342
- package/dist/node/presentation/features/templates/FeatureDataViewsTemplate/index.js +1 -342
- package/dist/node/presentation/features/templates/FeatureEventDetailTemplate/FeatureEventDetailTemplate.js +1 -303
- package/dist/node/presentation/features/templates/FeatureEventDetailTemplate/index.js +1 -303
- package/dist/node/presentation/features/templates/FeatureEventsTemplate/FeatureEventsTemplate.js +1 -340
- package/dist/node/presentation/features/templates/FeatureEventsTemplate/index.js +1 -340
- package/dist/node/presentation/features/templates/FeatureFormDetailTemplate/FeatureFormDetailTemplate.js +1 -329
- package/dist/node/presentation/features/templates/FeatureFormDetailTemplate/index.js +1 -329
- package/dist/node/presentation/features/templates/FeatureFormsTemplate/FeatureFormsTemplate.js +1 -340
- package/dist/node/presentation/features/templates/FeatureFormsTemplate/index.js +1 -340
- package/dist/node/presentation/features/templates/FeatureOperationDetailTemplate/FeatureOperationDetailTemplate.js +1 -302
- package/dist/node/presentation/features/templates/FeatureOperationDetailTemplate/index.js +1 -302
- package/dist/node/presentation/features/templates/FeatureOperationsTemplate/FeatureOperationsTemplate.js +1 -218
- package/dist/node/presentation/features/templates/FeatureOperationsTemplate/index.js +1 -218
- package/dist/node/presentation/features/templates/FeatureOverviewTemplate/FeatureOverviewTemplate.js +1 -187
- package/dist/node/presentation/features/templates/FeatureOverviewTemplate/index.js +1 -187
- package/dist/node/presentation/features/templates/FeaturePresentationDetailTemplate/FeaturePresentationDetailTemplate.js +1 -306
- package/dist/node/presentation/features/templates/FeaturePresentationDetailTemplate/index.js +1 -306
- package/dist/node/presentation/features/templates/FeaturePresentationsTemplate/FeaturePresentationsTemplate.js +1 -342
- package/dist/node/presentation/features/templates/FeaturePresentationsTemplate/index.js +1 -342
- package/dist/presentation/features/atoms/FeatureIcon/FeatureIcon.js +1 -97
- package/dist/presentation/features/atoms/FeatureIcon/index.js +1 -97
- package/dist/presentation/features/atoms/index.js +1 -97
- package/dist/presentation/features/hooks/index.js +1 -397
- package/dist/presentation/features/hooks/useContractsRegistry.js +1 -289
- package/dist/presentation/features/hooks/useFeatureFilters.js +1 -75
- package/dist/presentation/features/hooks/useFeatureRegistry.js +1 -147
- package/dist/presentation/features/hooks/useRelatedDocs.js +1 -28
- package/dist/presentation/features/index.js +1 -3063
- package/dist/presentation/features/molecules/FeatureCard/FeatureCard.js +1 -366
- package/dist/presentation/features/molecules/FeatureCard/index.js +1 -366
- package/dist/presentation/features/molecules/FeatureCategoryHeader/FeatureCategoryHeader.js +1 -50
- package/dist/presentation/features/molecules/FeatureCategoryHeader/index.js +1 -50
- package/dist/presentation/features/molecules/FeatureFilters/FeatureFilters.js +1 -92
- package/dist/presentation/features/molecules/FeatureFilters/index.js +1 -92
- package/dist/presentation/features/molecules/FeatureHoverPreview/FeatureHoverPreview.js +1 -176
- package/dist/presentation/features/molecules/FeatureHoverPreview/index.js +1 -176
- package/dist/presentation/features/molecules/index.js +1 -505
- package/dist/presentation/features/organisms/FeatureDataViewsList.js +1 -304
- package/dist/presentation/features/organisms/FeatureDetail/FeatureDetail.js +1 -154
- package/dist/presentation/features/organisms/FeatureDetail/index.js +1 -154
- package/dist/presentation/features/organisms/FeatureDiscovery/FeatureDiscovery.js +1 -909
- package/dist/presentation/features/organisms/FeatureDiscovery/index.js +1 -909
- package/dist/presentation/features/organisms/FeatureEventsList.js +1 -302
- package/dist/presentation/features/organisms/FeatureFormsList.js +1 -302
- package/dist/presentation/features/organisms/FeatureOperationsList.js +1 -180
- package/dist/presentation/features/organisms/FeaturePresentationsList.js +1 -304
- package/dist/presentation/features/organisms/index.js +1 -1359
- package/dist/presentation/features/templates/FeatureDataViewDetailTemplate/FeatureDataViewDetailTemplate.js +1 -332
- package/dist/presentation/features/templates/FeatureDataViewDetailTemplate/index.js +1 -332
- package/dist/presentation/features/templates/FeatureDataViewsTemplate/FeatureDataViewsTemplate.js +1 -342
- package/dist/presentation/features/templates/FeatureDataViewsTemplate/index.js +1 -342
- package/dist/presentation/features/templates/FeatureEventDetailTemplate/FeatureEventDetailTemplate.js +1 -303
- package/dist/presentation/features/templates/FeatureEventDetailTemplate/index.js +1 -303
- package/dist/presentation/features/templates/FeatureEventsTemplate/FeatureEventsTemplate.js +1 -340
- package/dist/presentation/features/templates/FeatureEventsTemplate/index.js +1 -340
- package/dist/presentation/features/templates/FeatureFormDetailTemplate/FeatureFormDetailTemplate.js +1 -329
- package/dist/presentation/features/templates/FeatureFormDetailTemplate/index.js +1 -329
- package/dist/presentation/features/templates/FeatureFormsTemplate/FeatureFormsTemplate.js +1 -340
- package/dist/presentation/features/templates/FeatureFormsTemplate/index.js +1 -340
- package/dist/presentation/features/templates/FeatureOperationDetailTemplate/FeatureOperationDetailTemplate.js +1 -302
- package/dist/presentation/features/templates/FeatureOperationDetailTemplate/index.js +1 -302
- package/dist/presentation/features/templates/FeatureOperationsTemplate/FeatureOperationsTemplate.js +1 -218
- package/dist/presentation/features/templates/FeatureOperationsTemplate/index.js +1 -218
- package/dist/presentation/features/templates/FeatureOverviewTemplate/FeatureOverviewTemplate.js +1 -187
- package/dist/presentation/features/templates/FeatureOverviewTemplate/index.js +1 -187
- package/dist/presentation/features/templates/FeaturePresentationDetailTemplate/FeaturePresentationDetailTemplate.js +1 -306
- package/dist/presentation/features/templates/FeaturePresentationDetailTemplate/index.js +1 -306
- package/dist/presentation/features/templates/FeaturePresentationsTemplate/FeaturePresentationsTemplate.js +1 -342
- package/dist/presentation/features/templates/FeaturePresentationsTemplate/index.js +1 -342
- package/package.json +103 -31
- package/src/components/docs/DocsIndexPage.tsx +55 -0
- package/src/components/docs/architecture/ArchitectureControlPlanePage.tsx +19 -0
- package/src/components/docs/architecture/ArchitectureOverviewPage.tsx +34 -0
- package/src/components/docs/docsManifest.test.ts +70 -0
- package/src/components/docs/docsManifest.ts +71 -1
- package/src/components/docs/ecosystem/PluginsPage.tsx +24 -10
- package/src/components/docs/ecosystem/RegistryPage.tsx +11 -6
- package/src/components/docs/generated/docs-index._common.json +206 -273
- package/src/components/docs/generated/docs-index.control-plane.json +18 -0
- package/src/components/docs/generated/docs-index.defineExample.json +10 -0
- package/src/components/docs/generated/docs-index.manifest.json +22 -12
- package/src/components/docs/generated/docs-index.platform-acp.json +64 -0
- package/src/components/docs/generated/docs-index.platform-agent.json +89 -1
- package/src/components/docs/generated/docs-index.platform-context.json +48 -0
- package/src/components/docs/generated/docs-index.platform-control-plane.json +72 -0
- package/src/components/docs/generated/docs-index.platform-database.json +40 -0
- package/src/components/docs/generated/docs-index.platform-docs.json +64 -0
- package/src/components/docs/generated/docs-index.platform-provider-ranking.json +89 -1
- package/src/components/docs/generated/docs-index.pocket-family-office.json +8 -0
- package/src/components/docs/generated/docs-index.unknown.json +8 -0
- package/src/components/docs/guides/GuideConnectInRepoPage.tsx +184 -0
- package/src/components/docs/guides/GuideFirstModuleBundlePage.tsx +182 -0
- package/src/components/docs/guides/GuideHostBuilderWorkbenchPage.tsx +230 -0
- package/src/components/docs/guides/GuidesIndexPage.tsx +21 -0
- package/src/components/docs/guides/index.ts +3 -0
- package/src/components/docs/specs/SpecsBuilderControlPlanePage.tsx +210 -0
- package/src/components/docs/specs/SpecsConnectPage.tsx +162 -0
- package/src/components/docs/specs/SpecsModuleBundlesPage.tsx +223 -0
- package/src/components/docs/specs/SpecsOverlaysPage.tsx +20 -0
- package/src/components/docs/specs/SpecsOverviewPage.tsx +44 -0
- package/src/components/docs/specs/index.ts +3 -0
- package/src/components/docs/studio/StudioOverviewPage.tsx +26 -0
- package/src/infrastructure/elysia/logger.ts +11 -3
|
@@ -1,2136 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
EmbeddingService,
|
|
4
|
-
VectorIndexer
|
|
5
|
-
} from "@contractspec/lib.knowledge/ingestion";
|
|
6
|
-
import {
|
|
7
|
-
ContextSnapshotPipeline,
|
|
8
|
-
PostgresContextStorage
|
|
9
|
-
} from "@contractspec/module.context-storage";
|
|
10
|
-
function createContextStorageService(options) {
|
|
11
|
-
const store = new PostgresContextStorage({
|
|
12
|
-
database: options.database,
|
|
13
|
-
schema: options.schema,
|
|
14
|
-
createTablesIfMissing: options.createTablesIfMissing
|
|
15
|
-
});
|
|
16
|
-
const embeddingService = options.embeddingProvider ? new EmbeddingService(options.embeddingProvider, options.embeddingBatchSize) : undefined;
|
|
17
|
-
const vectorIndexer = options.vectorStoreProvider && options.vectorIndex ? new VectorIndexer(options.vectorStoreProvider, options.vectorIndex) : undefined;
|
|
18
|
-
const pipeline = new ContextSnapshotPipeline({
|
|
19
|
-
store,
|
|
20
|
-
documentProcessor: options.documentProcessor,
|
|
21
|
-
embeddingService,
|
|
22
|
-
vectorIndexer
|
|
23
|
-
});
|
|
24
|
-
return { store, pipeline };
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// src/infrastructure/elysia/logger.ts
|
|
28
|
-
import { Logger, LogLevel } from "@contractspec/lib.logger";
|
|
29
|
-
var createAppLogger = () => new Logger({
|
|
30
|
-
level: LogLevel.INFO,
|
|
31
|
-
environment: "production",
|
|
32
|
-
enableTracing: true,
|
|
33
|
-
enableTiming: true,
|
|
34
|
-
enableContext: true,
|
|
35
|
-
enableColors: false
|
|
36
|
-
});
|
|
37
|
-
var appLogger = createAppLogger();
|
|
38
|
-
var dbLogger = new Logger({
|
|
39
|
-
level: LogLevel.WARN,
|
|
40
|
-
environment: "production",
|
|
41
|
-
enableTracing: true,
|
|
42
|
-
enableTiming: true,
|
|
43
|
-
enableContext: true,
|
|
44
|
-
enableColors: false
|
|
45
|
-
});
|
|
46
|
-
var authLogger = new Logger({
|
|
47
|
-
level: LogLevel.INFO,
|
|
48
|
-
environment: "production",
|
|
49
|
-
enableTracing: true,
|
|
50
|
-
enableTiming: true,
|
|
51
|
-
enableContext: true,
|
|
52
|
-
enableColors: false
|
|
53
|
-
});
|
|
54
|
-
// src/application/mcp/normalizeMcpRequest.ts
|
|
55
|
-
var REQUIRED_ACCEPT_TYPES = ["application/json", "text/event-stream"];
|
|
56
|
-
function canNormalizeAcceptHeader(acceptHeader) {
|
|
57
|
-
return !acceptHeader || acceptHeader.includes("*/*") || acceptHeader.includes("application/*") || REQUIRED_ACCEPT_TYPES.some((value) => acceptHeader.includes(value));
|
|
58
|
-
}
|
|
59
|
-
function normalizeMcpRequest(request) {
|
|
60
|
-
if (request.method !== "POST")
|
|
61
|
-
return request;
|
|
62
|
-
const acceptHeader = request.headers.get("accept");
|
|
63
|
-
if (!canNormalizeAcceptHeader(acceptHeader))
|
|
64
|
-
return request;
|
|
65
|
-
const missingTypes = REQUIRED_ACCEPT_TYPES.filter((value) => !acceptHeader?.includes(value));
|
|
66
|
-
if (missingTypes.length === 0)
|
|
67
|
-
return request;
|
|
68
|
-
const headers = new Headers(request.headers);
|
|
69
|
-
headers.set("accept", [acceptHeader, ...missingTypes].filter(Boolean).join(", "));
|
|
70
|
-
return new Request(request, { headers });
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// src/application/mcp/common.ts
|
|
74
|
-
import { createMcpServer } from "@contractspec/lib.contracts-runtime-server-mcp/provider-mcp";
|
|
75
|
-
import { PresentationRegistry } from "@contractspec/lib.contracts-spec/presentations";
|
|
76
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
77
|
-
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
78
|
-
import { randomUUID } from "crypto";
|
|
79
|
-
import { Elysia } from "elysia";
|
|
80
|
-
var baseCtx = {
|
|
81
|
-
actor: "anonymous",
|
|
82
|
-
decide: async () => ({ effect: "allow" })
|
|
83
|
-
};
|
|
84
|
-
function createJsonRpcErrorResponse(status, code, message, data) {
|
|
85
|
-
return new Response(JSON.stringify({
|
|
86
|
-
jsonrpc: "2.0",
|
|
87
|
-
error: {
|
|
88
|
-
code,
|
|
89
|
-
message,
|
|
90
|
-
...data ? { data } : {}
|
|
91
|
-
},
|
|
92
|
-
id: null
|
|
93
|
-
}), {
|
|
94
|
-
status,
|
|
95
|
-
headers: {
|
|
96
|
-
"content-type": "application/json"
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
function createSessionState({
|
|
101
|
-
logger,
|
|
102
|
-
serverName,
|
|
103
|
-
ops,
|
|
104
|
-
resources,
|
|
105
|
-
prompts,
|
|
106
|
-
presentations,
|
|
107
|
-
stateful
|
|
108
|
-
}) {
|
|
109
|
-
const server = new McpServer({
|
|
110
|
-
name: serverName,
|
|
111
|
-
version: "1.0.0"
|
|
112
|
-
}, {
|
|
113
|
-
capabilities: {
|
|
114
|
-
tools: {},
|
|
115
|
-
resources: {},
|
|
116
|
-
prompts: {},
|
|
117
|
-
logging: {}
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
logger.info("Setting up MCP server...");
|
|
121
|
-
createMcpServer(server, ops, resources, prompts, {
|
|
122
|
-
logger,
|
|
123
|
-
toolCtx: () => baseCtx,
|
|
124
|
-
promptCtx: () => ({ locale: "en" }),
|
|
125
|
-
resourceCtx: () => ({ locale: "en" }),
|
|
126
|
-
presentations: new PresentationRegistry(presentations)
|
|
127
|
-
});
|
|
128
|
-
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
129
|
-
sessionIdGenerator: stateful ? () => randomUUID() : undefined,
|
|
130
|
-
enableJsonResponse: true
|
|
131
|
-
});
|
|
132
|
-
return server.connect(transport).then(() => ({ server, transport }));
|
|
133
|
-
}
|
|
134
|
-
async function closeSessionState(state) {
|
|
135
|
-
await Promise.allSettled([state.transport.close(), state.server.close()]);
|
|
136
|
-
}
|
|
137
|
-
function toErrorMessage(error) {
|
|
138
|
-
return error instanceof Error ? error.stack ?? error.message : String(error);
|
|
139
|
-
}
|
|
140
|
-
function createMcpElysiaHandler({
|
|
141
|
-
logger,
|
|
142
|
-
path,
|
|
143
|
-
serverName,
|
|
144
|
-
ops,
|
|
145
|
-
resources,
|
|
146
|
-
prompts,
|
|
147
|
-
presentations,
|
|
148
|
-
validateAuth,
|
|
149
|
-
requiredAuthMethods
|
|
150
|
-
}) {
|
|
151
|
-
logger.info("Setting up MCP handler...", {
|
|
152
|
-
requiredAuthMethods: requiredAuthMethods ?? []
|
|
153
|
-
});
|
|
154
|
-
const isStateful = process.env.CONTRACTSPEC_MCP_STATEFUL === "1";
|
|
155
|
-
const sessions = new Map;
|
|
156
|
-
async function handleStateless(request) {
|
|
157
|
-
const state = await createSessionState({
|
|
158
|
-
logger,
|
|
159
|
-
path,
|
|
160
|
-
serverName,
|
|
161
|
-
ops,
|
|
162
|
-
resources,
|
|
163
|
-
prompts,
|
|
164
|
-
presentations,
|
|
165
|
-
stateful: false
|
|
166
|
-
});
|
|
167
|
-
try {
|
|
168
|
-
return await state.transport.handleRequest(normalizeMcpRequest(request));
|
|
169
|
-
} finally {
|
|
170
|
-
await closeSessionState(state);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
async function closeSession(sessionId) {
|
|
174
|
-
const state = sessions.get(sessionId);
|
|
175
|
-
if (!state)
|
|
176
|
-
return;
|
|
177
|
-
sessions.delete(sessionId);
|
|
178
|
-
await closeSessionState(state);
|
|
179
|
-
}
|
|
180
|
-
async function handleStateful(request) {
|
|
181
|
-
const requestedSessionId = request.headers.get("mcp-session-id");
|
|
182
|
-
let state;
|
|
183
|
-
let createdState = false;
|
|
184
|
-
if (requestedSessionId) {
|
|
185
|
-
const existing = sessions.get(requestedSessionId);
|
|
186
|
-
if (!existing) {
|
|
187
|
-
return createJsonRpcErrorResponse(404, -32001, "Session not found");
|
|
188
|
-
}
|
|
189
|
-
state = existing;
|
|
190
|
-
} else {
|
|
191
|
-
state = await createSessionState({
|
|
192
|
-
logger,
|
|
193
|
-
path,
|
|
194
|
-
serverName,
|
|
195
|
-
ops,
|
|
196
|
-
resources,
|
|
197
|
-
prompts,
|
|
198
|
-
presentations,
|
|
199
|
-
stateful: true
|
|
200
|
-
});
|
|
201
|
-
createdState = true;
|
|
202
|
-
}
|
|
203
|
-
try {
|
|
204
|
-
const response = await state.transport.handleRequest(normalizeMcpRequest(request));
|
|
205
|
-
const activeSessionId = state.transport.sessionId;
|
|
206
|
-
if (activeSessionId && !sessions.has(activeSessionId)) {
|
|
207
|
-
sessions.set(activeSessionId, state);
|
|
208
|
-
}
|
|
209
|
-
if (request.method === "DELETE" && activeSessionId) {
|
|
210
|
-
await closeSession(activeSessionId);
|
|
211
|
-
} else if (!activeSessionId && createdState) {
|
|
212
|
-
await closeSessionState(state);
|
|
213
|
-
}
|
|
214
|
-
return response;
|
|
215
|
-
} catch (error) {
|
|
216
|
-
if (createdState) {
|
|
217
|
-
await closeSessionState(state);
|
|
218
|
-
}
|
|
219
|
-
throw error;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
return new Elysia({ name: `mcp-${serverName}` }).all(path, async ({ request }) => {
|
|
223
|
-
try {
|
|
224
|
-
if (validateAuth) {
|
|
225
|
-
const authResult = await validateAuth(request);
|
|
226
|
-
if (!authResult.valid) {
|
|
227
|
-
return createJsonRpcErrorResponse(401, -32002, "Authentication failed", authResult.reason);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
if (isStateful) {
|
|
231
|
-
return await handleStateful(request);
|
|
232
|
-
}
|
|
233
|
-
return await handleStateless(request);
|
|
234
|
-
} catch (error) {
|
|
235
|
-
logger.error("Error handling MCP request", {
|
|
236
|
-
path,
|
|
237
|
-
method: request.method,
|
|
238
|
-
error: toErrorMessage(error)
|
|
239
|
-
});
|
|
240
|
-
return createJsonRpcErrorResponse(500, -32000, "Internal error");
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// src/application/mcp/cliMcp.ts
|
|
246
|
-
import fs from "node:fs/promises";
|
|
247
|
-
import {
|
|
248
|
-
defineCommand,
|
|
249
|
-
definePrompt,
|
|
250
|
-
defineResourceTemplate,
|
|
251
|
-
installOp,
|
|
252
|
-
OperationSpecRegistry,
|
|
253
|
-
PromptRegistry,
|
|
254
|
-
ResourceRegistry
|
|
255
|
-
} from "@contractspec/lib.contracts-spec";
|
|
256
|
-
import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
|
|
257
|
-
import path from "path";
|
|
258
|
-
import z from "zod";
|
|
259
|
-
var __dirname = "/home/runner/work/contractspec/contractspec/packages/bundles/library/src/application/mcp";
|
|
260
|
-
var CLI_DOC_PATHS = {
|
|
261
|
-
quickstart: "packages/apps/cli-contractspec/QUICK_START.md",
|
|
262
|
-
reference: "packages/apps/cli-contractspec/QUICK_REFERENCE.md",
|
|
263
|
-
readme: "packages/apps/cli-contractspec/README.md"
|
|
264
|
-
};
|
|
265
|
-
var CLI_DOC_FALLBACK = {
|
|
266
|
-
quickstart: `# ContractSpec CLI quickstart
|
|
1
|
+
import{EmbeddingService as sj,VectorIndexer as rj}from"@contractspec/lib.knowledge/ingestion";import{ContextSnapshotPipeline as ej,PostgresContextStorage as jY}from"@contractspec/module.context-storage";function xJ(j){let Y=new jY({database:j.database,schema:j.schema,createTablesIfMissing:j.createTablesIfMissing}),J=j.embeddingProvider?new sj(j.embeddingProvider,j.embeddingBatchSize):void 0,Q=j.vectorStoreProvider&&j.vectorIndex?new rj(j.vectorStoreProvider,j.vectorIndex):void 0,$=new ej({store:Y,documentProcessor:j.documentProcessor,embeddingService:J,vectorIndexer:Q});return{store:Y,pipeline:$}}import{Logger as Wj,LogLevel as xj}from"@contractspec/lib.logger";function Pj(){return"production"}var YY=()=>new Wj({level:xj.INFO,environment:Pj(),enableTracing:!0,enableTiming:!0,enableContext:!0,enableColors:!1}),M=YY(),LJ=new Wj({level:xj.WARN,environment:Pj(),enableTracing:!0,enableTiming:!0,enableContext:!0,enableColors:!1}),GJ=new Wj({level:xj.INFO,environment:Pj(),enableTracing:!0,enableTiming:!0,enableContext:!0,enableColors:!1});var Ij=["application/json","text/event-stream"];function JY(j){return!j||j.includes("*/*")||j.includes("application/*")||Ij.some((Y)=>j.includes(Y))}function qj(j){if(j.method!=="POST")return j;let Y=j.headers.get("accept");if(!JY(Y))return j;let J=Ij.filter(($)=>!Y?.includes($));if(J.length===0)return j;let Q=new Headers(j.headers);return Q.set("accept",[Y,...J].filter(Boolean).join(", ")),new Request(j,{headers:Q})}import{createMcpServer as QY}from"@contractspec/lib.contracts-runtime-server-mcp/provider-mcp";import{PresentationRegistry as ZY}from"@contractspec/lib.contracts-spec/presentations";import{McpServer as $Y}from"@modelcontextprotocol/sdk/server/mcp.js";import{WebStandardStreamableHTTPServerTransport as XY}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{randomUUID as UY}from"crypto";import{Elysia as VY}from"elysia";var HY={actor:"anonymous",decide:async()=>({effect:"allow"})};function Lj(j,Y,J,Q){return new Response(JSON.stringify({jsonrpc:"2.0",error:{code:Y,message:J,...Q?{data:Q}:{}},id:null}),{status:j,headers:{"content-type":"application/json"}})}function Ej({logger:j,serverName:Y,ops:J,resources:Q,prompts:$,presentations:Z,stateful:X}){let U=new $Y({name:Y,version:"1.0.0"},{capabilities:{tools:{},resources:{},prompts:{},logging:{}}});j.info("Setting up MCP server..."),QY(U,J,Q,$,{logger:j,toolCtx:()=>HY,promptCtx:()=>({locale:"en"}),resourceCtx:()=>({locale:"en"}),presentations:new ZY(Z)});let K=new XY({sessionIdGenerator:X?()=>UY():void 0,enableJsonResponse:!0});return U.connect(K).then(()=>({server:U,transport:K}))}async function t(j){await Promise.allSettled([j.transport.close(),j.server.close()])}function KY(j){return j instanceof Error?j.stack??j.message:String(j)}function b({logger:j,path:Y,serverName:J,ops:Q,resources:$,prompts:Z,presentations:X,validateAuth:U,requiredAuthMethods:K}){j.info("Setting up MCP handler...",{requiredAuthMethods:K??[]});let P=process.env.CONTRACTSPEC_MCP_STATEFUL==="1",V=new Map;async function H(F){let W=await Ej({logger:j,path:Y,serverName:J,ops:Q,resources:$,prompts:Z,presentations:X,stateful:!1});try{return await W.transport.handleRequest(qj(F))}finally{await t(W)}}async function G(F){let W=V.get(F);if(!W)return;V.delete(F),await t(W)}async function Fj(F){let W=F.headers.get("mcp-session-id"),D,u=!1;if(W){let N=V.get(W);if(!N)return Lj(404,-32001,"Session not found");D=N}else D=await Ej({logger:j,path:Y,serverName:J,ops:Q,resources:$,prompts:Z,presentations:X,stateful:!0}),u=!0;try{let N=await D.transport.handleRequest(qj(F)),O=D.transport.sessionId;if(O&&!V.has(O))V.set(O,D);if(F.method==="DELETE"&&O)await G(O);else if(!O&&u)await t(D);return N}catch(N){if(u)await t(D);throw N}}return new VY({name:`mcp-${J}`}).all(Y,async({request:F})=>{try{if(U){let W=await U(F);if(!W.valid)return Lj(401,-32002,"Authentication failed",W.reason)}if(P)return await Fj(F);return await H(F)}catch(W){return j.error("Error handling MCP request",{path:Y,method:F.method,error:KY(W)}),Lj(500,-32000,"Internal error")}})}import BY from"node:fs/promises";import{defineCommand as wY,definePrompt as FY,defineResourceTemplate as zj,installOp as WY,OperationSpecRegistry as xY,PromptRegistry as PY,ResourceRegistry as qY}from"@contractspec/lib.contracts-spec";import{defineSchemaModel as Oj,ScalarTypeEnum as d}from"@contractspec/lib.schema";import l from"path";import k from"zod";var __dirname="/home/runner/work/contractspec/contractspec/packages/bundles/library/src/application/mcp",LY={quickstart:"packages/apps/cli-contractspec/QUICK_START.md",reference:"packages/apps/cli-contractspec/QUICK_REFERENCE.md",readme:"packages/apps/cli-contractspec/README.md"},GY={quickstart:`# ContractSpec CLI quickstart
|
|
267
2
|
|
|
268
3
|
contractspec create
|
|
269
4
|
contractspec build <spec>
|
|
270
|
-
contractspec validate <spec>`,
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
};
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
var
|
|
281
|
-
|
|
282
|
-
process.cwd(),
|
|
283
|
-
path.resolve(process.cwd(), ".."),
|
|
284
|
-
path.resolve(process.cwd(), "../.."),
|
|
285
|
-
path.resolve(process.cwd(), "../../..")
|
|
286
|
-
]);
|
|
287
|
-
if (typeof __dirname === "string") {
|
|
288
|
-
roots.add(path.resolve(__dirname, "../../../../.."));
|
|
289
|
-
}
|
|
290
|
-
return [...roots];
|
|
291
|
-
})();
|
|
292
|
-
var docCache = new Map;
|
|
293
|
-
async function loadCliDoc(key) {
|
|
294
|
-
if (docCache.has(key)) {
|
|
295
|
-
return docCache.get(key);
|
|
296
|
-
}
|
|
297
|
-
const relative = CLI_DOC_PATHS[key];
|
|
298
|
-
for (const root of candidateRoots) {
|
|
299
|
-
const candidate = path.resolve(root, relative);
|
|
300
|
-
try {
|
|
301
|
-
const data = await fs.readFile(candidate, "utf8");
|
|
302
|
-
docCache.set(key, data);
|
|
303
|
-
return data;
|
|
304
|
-
} catch {}
|
|
305
|
-
}
|
|
306
|
-
const fallback = CLI_DOC_FALLBACK[key];
|
|
307
|
-
docCache.set(key, fallback);
|
|
308
|
-
return fallback;
|
|
309
|
-
}
|
|
310
|
-
function buildCliResources() {
|
|
311
|
-
const resources = new ResourceRegistry;
|
|
312
|
-
resources.register(defineResourceTemplate({
|
|
313
|
-
meta: {
|
|
314
|
-
uriTemplate: "cli://doc/{slug}",
|
|
315
|
-
title: "CLI documentation",
|
|
316
|
-
description: "Quickstart, reference, and README for the CLI.",
|
|
317
|
-
mimeType: "text/markdown",
|
|
318
|
-
tags: CLI_DOC_TAGS
|
|
319
|
-
},
|
|
320
|
-
input: z.object({
|
|
321
|
-
slug: z.enum(["quickstart", "reference", "readme"])
|
|
322
|
-
}),
|
|
323
|
-
resolve: async ({ slug }) => {
|
|
324
|
-
const data = await loadCliDoc(slug);
|
|
325
|
-
return {
|
|
326
|
-
uri: `cli://doc/${slug}`,
|
|
327
|
-
mimeType: "text/markdown",
|
|
328
|
-
data
|
|
329
|
-
};
|
|
330
|
-
}
|
|
331
|
-
}));
|
|
332
|
-
resources.register(defineResourceTemplate({
|
|
333
|
-
meta: {
|
|
334
|
-
uriTemplate: "cli://commands",
|
|
335
|
-
title: "CLI commands summary",
|
|
336
|
-
description: "Key ContractSpec CLI commands and when to use them.",
|
|
337
|
-
mimeType: "application/json",
|
|
338
|
-
tags: CLI_DOC_TAGS
|
|
339
|
-
},
|
|
340
|
-
input: z.object({}),
|
|
341
|
-
resolve: async () => {
|
|
342
|
-
const commands = [
|
|
343
|
-
{
|
|
344
|
-
command: "contractspec create",
|
|
345
|
-
summary: "Interactive wizard to author specs (with optional AI).",
|
|
346
|
-
doc: "cli://doc/quickstart"
|
|
347
|
-
},
|
|
348
|
-
{
|
|
349
|
-
command: "contractspec build <specPath>",
|
|
350
|
-
summary: "Generate implementation code from a ContractSpec (agents + templates).",
|
|
351
|
-
doc: "cli://doc/reference"
|
|
352
|
-
},
|
|
353
|
-
{
|
|
354
|
-
command: "contractspec validate <specPath>",
|
|
355
|
-
summary: "Validate specs and optionally check implementations against them.",
|
|
356
|
-
doc: "cli://doc/reference"
|
|
357
|
-
}
|
|
358
|
-
];
|
|
359
|
-
return {
|
|
360
|
-
uri: "cli://commands",
|
|
361
|
-
mimeType: "application/json",
|
|
362
|
-
data: JSON.stringify(commands, null, 2)
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
}));
|
|
366
|
-
return resources;
|
|
367
|
-
}
|
|
368
|
-
function buildCliPrompts() {
|
|
369
|
-
const prompts = new PromptRegistry;
|
|
370
|
-
prompts.register(definePrompt({
|
|
371
|
-
meta: {
|
|
372
|
-
key: "cli.usage",
|
|
373
|
-
version: "1.0.0",
|
|
374
|
-
title: "Use ContractSpec CLI safely",
|
|
375
|
-
description: "Remind agents to read CLI docs and pick commands from the canonical list.",
|
|
376
|
-
tags: CLI_DOC_TAGS,
|
|
377
|
-
stability: "beta",
|
|
378
|
-
owners: CLI_OWNERS
|
|
379
|
-
},
|
|
380
|
-
args: [
|
|
381
|
-
{
|
|
382
|
-
name: "goal",
|
|
383
|
-
description: "Task the user wants to achieve.",
|
|
384
|
-
required: false,
|
|
385
|
-
schema: z.string().optional()
|
|
386
|
-
}
|
|
387
|
-
],
|
|
388
|
-
input: z.object({ goal: z.string().optional() }),
|
|
389
|
-
render: async ({ goal }) => [
|
|
390
|
-
{
|
|
391
|
-
type: "text",
|
|
392
|
-
text: `Use CLI commands only from cli://commands. Prefer quickstart for newcomers and reference for options.${goal ? ` Goal: ${goal}.` : ""}`
|
|
393
|
-
},
|
|
394
|
-
{ type: "resource", uri: "cli://commands", title: "Commands" },
|
|
395
|
-
{
|
|
396
|
-
type: "resource",
|
|
397
|
-
uri: "cli://doc/quickstart",
|
|
398
|
-
title: "Quickstart"
|
|
399
|
-
}
|
|
400
|
-
]
|
|
401
|
-
}));
|
|
402
|
-
return prompts;
|
|
403
|
-
}
|
|
404
|
-
function buildCliOps() {
|
|
405
|
-
const registry = new OperationSpecRegistry;
|
|
406
|
-
const CliSuggestInput = defineSchemaModel({
|
|
407
|
-
name: "CliSuggestInput",
|
|
408
|
-
fields: {
|
|
409
|
-
goal: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
410
|
-
prefersAi: { type: ScalarTypeEnum.Boolean(), isOptional: true }
|
|
411
|
-
}
|
|
412
|
-
});
|
|
413
|
-
const CliSuggestOutput = defineSchemaModel({
|
|
414
|
-
name: "CliSuggestOutput",
|
|
415
|
-
fields: {
|
|
416
|
-
command: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
417
|
-
docUri: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
418
|
-
reason: { type: ScalarTypeEnum.String_unsecure(), isOptional: false }
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
const suggestSpec = defineCommand({
|
|
422
|
-
meta: {
|
|
423
|
-
key: "cli_suggestCommand",
|
|
424
|
-
version: "1.0.0",
|
|
425
|
-
stability: "stable",
|
|
426
|
-
owners: CLI_OWNERS,
|
|
427
|
-
tags: CLI_DOC_TAGS,
|
|
428
|
-
description: "Recommend a CLI command for the requested goal.",
|
|
429
|
-
goal: "Help AI agents choose the correct CLI entrypoint quickly.",
|
|
430
|
-
context: "Used inside the CLI MCP server."
|
|
431
|
-
},
|
|
432
|
-
io: {
|
|
433
|
-
input: CliSuggestInput,
|
|
434
|
-
output: CliSuggestOutput
|
|
435
|
-
},
|
|
436
|
-
policy: {
|
|
437
|
-
auth: "anonymous"
|
|
438
|
-
}
|
|
439
|
-
});
|
|
440
|
-
installOp(registry, suggestSpec, async ({ goal, prefersAi }) => {
|
|
441
|
-
const lower = goal.toLowerCase();
|
|
442
|
-
if (lower.includes("create") || lower.includes("new")) {
|
|
443
|
-
return {
|
|
444
|
-
command: prefersAi ? "contractspec create --ai" : "contractspec create",
|
|
445
|
-
docUri: "cli://doc/quickstart",
|
|
446
|
-
reason: "Creates a new ContractSpec interactively (optionally with AI)."
|
|
447
|
-
};
|
|
448
|
-
}
|
|
449
|
-
if (lower.includes("build") || lower.includes("generate")) {
|
|
450
|
-
return {
|
|
451
|
-
command: "contractspec build <path-to-spec>",
|
|
452
|
-
docUri: "cli://doc/reference",
|
|
453
|
-
reason: "Builds implementation code from a spec using agents + templates."
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
if (lower.includes("validate") || lower.includes("check")) {
|
|
457
|
-
return {
|
|
458
|
-
command: "contractspec validate <path-to-spec>",
|
|
459
|
-
docUri: "cli://doc/reference",
|
|
460
|
-
reason: "Validates a spec and optionally checks its implementation for drift."
|
|
461
|
-
};
|
|
462
|
-
}
|
|
463
|
-
return {
|
|
464
|
-
command: "contractspec --help",
|
|
465
|
-
docUri: "cli://doc/readme",
|
|
466
|
-
reason: "Fallback when the goal is unclear; read README for options."
|
|
467
|
-
};
|
|
468
|
-
});
|
|
469
|
-
return registry;
|
|
470
|
-
}
|
|
471
|
-
function createCliMcpHandler(path2 = "/api/mcp/cli") {
|
|
472
|
-
return createMcpElysiaHandler({
|
|
473
|
-
logger: appLogger,
|
|
474
|
-
path: path2,
|
|
475
|
-
serverName: "contractspec-cli-mcp",
|
|
476
|
-
ops: buildCliOps(),
|
|
477
|
-
resources: buildCliResources(),
|
|
478
|
-
prompts: buildCliPrompts()
|
|
479
|
-
});
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
// src/application/mcp/contractsMcpResources.ts
|
|
483
|
-
import {
|
|
484
|
-
definePrompt as definePrompt2,
|
|
485
|
-
defineResourceTemplate as defineResourceTemplate2,
|
|
486
|
-
PromptRegistry as PromptRegistry2,
|
|
487
|
-
ResourceRegistry as ResourceRegistry2
|
|
488
|
-
} from "@contractspec/lib.contracts-spec";
|
|
489
|
-
import z2 from "zod";
|
|
490
|
-
var OWNERS = ["@contractspec"];
|
|
491
|
-
var TAGS = ["contracts", "mcp"];
|
|
492
|
-
function buildContractsResources(services) {
|
|
493
|
-
const resources = new ResourceRegistry2;
|
|
494
|
-
resources.register(defineResourceTemplate2({
|
|
495
|
-
meta: {
|
|
496
|
-
uriTemplate: "contracts://list",
|
|
497
|
-
title: "Contract specs list",
|
|
498
|
-
description: "JSON list of all contract specs in the workspace.",
|
|
499
|
-
mimeType: "application/json",
|
|
500
|
-
tags: TAGS
|
|
501
|
-
},
|
|
502
|
-
input: z2.object({}),
|
|
503
|
-
resolve: async () => {
|
|
504
|
-
const specs = await services.listSpecs();
|
|
505
|
-
return {
|
|
506
|
-
uri: "contracts://list",
|
|
507
|
-
mimeType: "application/json",
|
|
508
|
-
data: JSON.stringify(specs, null, 2)
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
}));
|
|
512
|
-
resources.register(defineResourceTemplate2({
|
|
513
|
-
meta: {
|
|
514
|
-
uriTemplate: "contracts://spec/{path}",
|
|
515
|
-
title: "Contract spec content",
|
|
516
|
-
description: "Read a single contract spec file by path.",
|
|
517
|
-
mimeType: "text/plain",
|
|
518
|
-
tags: TAGS
|
|
519
|
-
},
|
|
520
|
-
input: z2.object({ path: z2.string() }),
|
|
521
|
-
resolve: async ({ path: path2 }) => {
|
|
522
|
-
const result = await services.getSpec(path2);
|
|
523
|
-
if (!result) {
|
|
524
|
-
return {
|
|
525
|
-
uri: `contracts://spec/${encodeURIComponent(path2)}`,
|
|
526
|
-
mimeType: "text/plain",
|
|
527
|
-
data: `Spec not found: ${path2}`
|
|
528
|
-
};
|
|
529
|
-
}
|
|
530
|
-
return {
|
|
531
|
-
uri: `contracts://spec/${encodeURIComponent(path2)}`,
|
|
532
|
-
mimeType: "text/plain",
|
|
533
|
-
data: result.content
|
|
534
|
-
};
|
|
535
|
-
}
|
|
536
|
-
}));
|
|
537
|
-
resources.register(defineResourceTemplate2({
|
|
538
|
-
meta: {
|
|
539
|
-
uriTemplate: "contracts://registry/manifest",
|
|
540
|
-
title: "Remote registry manifest",
|
|
541
|
-
description: "Contract registry manifest from the remote server.",
|
|
542
|
-
mimeType: "application/json",
|
|
543
|
-
tags: TAGS
|
|
544
|
-
},
|
|
545
|
-
input: z2.object({}),
|
|
546
|
-
resolve: async () => {
|
|
547
|
-
const manifest = await services.fetchRegistryManifest();
|
|
548
|
-
return {
|
|
549
|
-
uri: "contracts://registry/manifest",
|
|
550
|
-
mimeType: "application/json",
|
|
551
|
-
data: JSON.stringify(manifest, null, 2)
|
|
552
|
-
};
|
|
553
|
-
}
|
|
554
|
-
}));
|
|
555
|
-
return resources;
|
|
556
|
-
}
|
|
557
|
-
function buildContractsPrompts() {
|
|
558
|
-
const prompts = new PromptRegistry2;
|
|
559
|
-
prompts.register(definePrompt2({
|
|
560
|
-
meta: {
|
|
561
|
-
key: "contracts.editor",
|
|
562
|
-
version: "1.0.0",
|
|
563
|
-
title: "Contract editing guide",
|
|
564
|
-
description: "Guide AI agents through reading, editing, and validating contracts.",
|
|
565
|
-
tags: TAGS,
|
|
566
|
-
stability: "beta",
|
|
567
|
-
owners: OWNERS
|
|
568
|
-
},
|
|
569
|
-
args: [
|
|
570
|
-
{
|
|
571
|
-
name: "goal",
|
|
572
|
-
description: "What the agent wants to achieve with the contract.",
|
|
573
|
-
required: false,
|
|
574
|
-
schema: z2.string().optional()
|
|
575
|
-
}
|
|
576
|
-
],
|
|
577
|
-
input: z2.object({ goal: z2.string().optional() }),
|
|
578
|
-
render: async ({ goal }) => [
|
|
579
|
-
{
|
|
580
|
-
type: "text",
|
|
581
|
-
text: [
|
|
582
|
-
"Contract editing workflow:",
|
|
583
|
-
"1. Use contracts.list to discover specs",
|
|
584
|
-
"2. Use contracts.get to read a spec",
|
|
585
|
-
"3. Edit content and call contracts.update",
|
|
586
|
-
"4. Run contracts.validate to verify changes",
|
|
587
|
-
"5. Run contracts.build to regenerate artifacts",
|
|
588
|
-
goal ? `Agent goal: ${goal}` : ""
|
|
589
|
-
].filter(Boolean).join(`
|
|
590
|
-
`)
|
|
591
|
-
},
|
|
592
|
-
{
|
|
593
|
-
type: "resource",
|
|
594
|
-
uri: "contracts://list",
|
|
595
|
-
title: "Available contracts"
|
|
596
|
-
}
|
|
597
|
-
]
|
|
598
|
-
}));
|
|
599
|
-
return prompts;
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
// src/application/mcp/contractsMcpTools.ts
|
|
603
|
-
import {
|
|
604
|
-
defineCommand as defineCommand2,
|
|
605
|
-
installOp as installOp2,
|
|
606
|
-
OperationSpecRegistry as OperationSpecRegistry2
|
|
607
|
-
} from "@contractspec/lib.contracts-spec";
|
|
608
|
-
import { defineSchemaModel as defineSchemaModel2, ScalarTypeEnum as ScalarTypeEnum2 } from "@contractspec/lib.schema";
|
|
609
|
-
var OWNERS2 = ["@contractspec"];
|
|
610
|
-
var TAGS2 = ["contracts", "mcp"];
|
|
611
|
-
function buildContractsOps(services) {
|
|
612
|
-
const registry = new OperationSpecRegistry2;
|
|
613
|
-
const ListInput = defineSchemaModel2({
|
|
614
|
-
name: "ContractsListInput",
|
|
615
|
-
fields: {
|
|
616
|
-
pattern: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true },
|
|
617
|
-
type: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true }
|
|
618
|
-
}
|
|
619
|
-
});
|
|
620
|
-
const ListOutput = defineSchemaModel2({
|
|
621
|
-
name: "ContractsListOutput",
|
|
622
|
-
fields: {
|
|
623
|
-
specs: { type: ScalarTypeEnum2.JSON(), isOptional: false },
|
|
624
|
-
total: { type: ScalarTypeEnum2.Int_unsecure(), isOptional: false }
|
|
625
|
-
}
|
|
626
|
-
});
|
|
627
|
-
installOp2(registry, defineCommand2({
|
|
628
|
-
meta: {
|
|
629
|
-
key: "contracts.list",
|
|
630
|
-
version: "1.0.0",
|
|
631
|
-
stability: "beta",
|
|
632
|
-
owners: OWNERS2,
|
|
633
|
-
tags: TAGS2,
|
|
634
|
-
description: "List contract specs in the workspace.",
|
|
635
|
-
goal: "Discover available contracts by type, pattern, or owner.",
|
|
636
|
-
context: "Contracts MCP server."
|
|
637
|
-
},
|
|
638
|
-
io: { input: ListInput, output: ListOutput },
|
|
639
|
-
policy: { auth: "anonymous" }
|
|
640
|
-
}), async ({ pattern, type }) => {
|
|
641
|
-
const specs = await services.listSpecs({ pattern, type });
|
|
642
|
-
return { specs, total: specs.length };
|
|
643
|
-
});
|
|
644
|
-
const GetInput = defineSchemaModel2({
|
|
645
|
-
name: "ContractsGetInput",
|
|
646
|
-
fields: {
|
|
647
|
-
path: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
|
|
648
|
-
}
|
|
649
|
-
});
|
|
650
|
-
const GetOutput = defineSchemaModel2({
|
|
651
|
-
name: "ContractsGetOutput",
|
|
652
|
-
fields: {
|
|
653
|
-
content: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
|
|
654
|
-
info: { type: ScalarTypeEnum2.JSON(), isOptional: false }
|
|
655
|
-
}
|
|
656
|
-
});
|
|
657
|
-
installOp2(registry, defineCommand2({
|
|
658
|
-
meta: {
|
|
659
|
-
key: "contracts.get",
|
|
660
|
-
version: "1.0.0",
|
|
661
|
-
stability: "beta",
|
|
662
|
-
owners: OWNERS2,
|
|
663
|
-
tags: TAGS2,
|
|
664
|
-
description: "Read a single contract spec file.",
|
|
665
|
-
goal: "Fetch spec content and parsed metadata.",
|
|
666
|
-
context: "Contracts MCP server."
|
|
667
|
-
},
|
|
668
|
-
io: { input: GetInput, output: GetOutput },
|
|
669
|
-
policy: { auth: "anonymous" }
|
|
670
|
-
}), async ({ path: path2 }) => {
|
|
671
|
-
const result = await services.getSpec(path2);
|
|
672
|
-
if (!result)
|
|
673
|
-
throw new Error(`Spec not found: ${path2}`);
|
|
674
|
-
return result;
|
|
675
|
-
});
|
|
676
|
-
const ValidateInput = defineSchemaModel2({
|
|
677
|
-
name: "ContractsValidateInput",
|
|
678
|
-
fields: {
|
|
679
|
-
path: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
|
|
680
|
-
}
|
|
681
|
-
});
|
|
682
|
-
const ValidateOutput = defineSchemaModel2({
|
|
683
|
-
name: "ContractsValidateOutput",
|
|
684
|
-
fields: {
|
|
685
|
-
valid: { type: ScalarTypeEnum2.Boolean(), isOptional: false },
|
|
686
|
-
errors: { type: ScalarTypeEnum2.JSON(), isOptional: false },
|
|
687
|
-
warnings: { type: ScalarTypeEnum2.JSON(), isOptional: false }
|
|
688
|
-
}
|
|
689
|
-
});
|
|
690
|
-
installOp2(registry, defineCommand2({
|
|
691
|
-
meta: {
|
|
692
|
-
key: "contracts.validate",
|
|
693
|
-
version: "1.0.0",
|
|
694
|
-
stability: "beta",
|
|
695
|
-
owners: OWNERS2,
|
|
696
|
-
tags: TAGS2,
|
|
697
|
-
description: "Validate a contract spec structure.",
|
|
698
|
-
goal: "Check spec for structural or policy issues.",
|
|
699
|
-
context: "Contracts MCP server."
|
|
700
|
-
},
|
|
701
|
-
io: { input: ValidateInput, output: ValidateOutput },
|
|
702
|
-
policy: { auth: "anonymous" }
|
|
703
|
-
}), async ({ path: path2 }) => services.validateSpec(path2));
|
|
704
|
-
const BuildInput = defineSchemaModel2({
|
|
705
|
-
name: "ContractsBuildInput",
|
|
706
|
-
fields: {
|
|
707
|
-
path: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
|
|
708
|
-
dryRun: { type: ScalarTypeEnum2.Boolean(), isOptional: true }
|
|
709
|
-
}
|
|
710
|
-
});
|
|
711
|
-
const BuildOutput = defineSchemaModel2({
|
|
712
|
-
name: "ContractsBuildOutput",
|
|
713
|
-
fields: {
|
|
714
|
-
results: { type: ScalarTypeEnum2.JSON(), isOptional: false }
|
|
715
|
-
}
|
|
716
|
-
});
|
|
717
|
-
installOp2(registry, defineCommand2({
|
|
718
|
-
meta: {
|
|
719
|
-
key: "contracts.build",
|
|
720
|
-
version: "1.0.0",
|
|
721
|
-
stability: "beta",
|
|
722
|
-
owners: OWNERS2,
|
|
723
|
-
tags: TAGS2,
|
|
724
|
-
description: "Generate implementation code from a contract spec.",
|
|
725
|
-
goal: "Produce handler, component, or test skeletons.",
|
|
726
|
-
context: "Contracts MCP server."
|
|
727
|
-
},
|
|
728
|
-
io: { input: BuildInput, output: BuildOutput },
|
|
729
|
-
policy: { auth: "user" }
|
|
730
|
-
}), async ({ path: path2, dryRun }) => services.buildSpec(path2, { dryRun }));
|
|
731
|
-
registerMutationTools(registry, services);
|
|
732
|
-
return registry;
|
|
733
|
-
}
|
|
734
|
-
function registerMutationTools(registry, services) {
|
|
735
|
-
const UpdateInput = defineSchemaModel2({
|
|
736
|
-
name: "ContractsUpdateInput",
|
|
737
|
-
fields: {
|
|
738
|
-
path: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
|
|
739
|
-
content: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true },
|
|
740
|
-
fields: { type: ScalarTypeEnum2.JSON(), isOptional: true }
|
|
741
|
-
}
|
|
742
|
-
});
|
|
743
|
-
const UpdateOutput = defineSchemaModel2({
|
|
744
|
-
name: "ContractsUpdateOutput",
|
|
745
|
-
fields: {
|
|
746
|
-
updated: { type: ScalarTypeEnum2.Boolean(), isOptional: false },
|
|
747
|
-
errors: { type: ScalarTypeEnum2.JSON(), isOptional: false },
|
|
748
|
-
warnings: { type: ScalarTypeEnum2.JSON(), isOptional: false }
|
|
749
|
-
}
|
|
750
|
-
});
|
|
751
|
-
installOp2(registry, defineCommand2({
|
|
752
|
-
meta: {
|
|
753
|
-
key: "contracts.update",
|
|
754
|
-
version: "1.0.0",
|
|
755
|
-
stability: "beta",
|
|
756
|
-
owners: OWNERS2,
|
|
757
|
-
tags: TAGS2,
|
|
758
|
-
description: "Update an existing contract spec.",
|
|
759
|
-
goal: "Modify spec content or individual fields with validation.",
|
|
760
|
-
context: "Contracts MCP server."
|
|
761
|
-
},
|
|
762
|
-
io: { input: UpdateInput, output: UpdateOutput },
|
|
763
|
-
policy: { auth: "user" }
|
|
764
|
-
}), async ({ path: path2, content, fields }) => services.updateSpec(path2, {
|
|
765
|
-
content,
|
|
766
|
-
fields: Array.isArray(fields) ? fields : undefined
|
|
767
|
-
}));
|
|
768
|
-
const DeleteInput = defineSchemaModel2({
|
|
769
|
-
name: "ContractsDeleteInput",
|
|
770
|
-
fields: {
|
|
771
|
-
path: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
|
|
772
|
-
clean: { type: ScalarTypeEnum2.Boolean(), isOptional: true }
|
|
773
|
-
}
|
|
774
|
-
});
|
|
775
|
-
const DeleteOutput = defineSchemaModel2({
|
|
776
|
-
name: "ContractsDeleteOutput",
|
|
777
|
-
fields: {
|
|
778
|
-
deleted: { type: ScalarTypeEnum2.Boolean(), isOptional: false },
|
|
779
|
-
cleanedFiles: { type: ScalarTypeEnum2.JSON(), isOptional: false },
|
|
780
|
-
errors: { type: ScalarTypeEnum2.JSON(), isOptional: false }
|
|
781
|
-
}
|
|
782
|
-
});
|
|
783
|
-
installOp2(registry, defineCommand2({
|
|
784
|
-
meta: {
|
|
785
|
-
key: "contracts.delete",
|
|
786
|
-
version: "1.0.0",
|
|
787
|
-
stability: "beta",
|
|
788
|
-
owners: OWNERS2,
|
|
789
|
-
tags: TAGS2,
|
|
790
|
-
description: "Delete a contract spec and optionally its artifacts.",
|
|
791
|
-
goal: "Remove a spec file and clean generated handlers/tests.",
|
|
792
|
-
context: "Contracts MCP server."
|
|
793
|
-
},
|
|
794
|
-
io: { input: DeleteInput, output: DeleteOutput },
|
|
795
|
-
policy: { auth: "user" }
|
|
796
|
-
}), async ({ path: path2, clean }) => services.deleteSpec(path2, { clean }));
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
// src/application/mcp/contractsMcp.ts
|
|
800
|
-
function createContractsMcpHandler(path2 = "/api/mcp/contracts", services) {
|
|
801
|
-
return createMcpElysiaHandler({
|
|
802
|
-
logger: appLogger,
|
|
803
|
-
path: path2,
|
|
804
|
-
serverName: "contractspec-contracts-mcp",
|
|
805
|
-
ops: buildContractsOps(services),
|
|
806
|
-
resources: buildContractsResources(services),
|
|
807
|
-
prompts: buildContractsPrompts()
|
|
808
|
-
});
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
// src/application/mcp/docsMcp.data.ts
|
|
812
|
-
import { defaultDocRegistry } from "@contractspec/lib.contracts-spec/docs";
|
|
813
|
-
var DEFAULT_LIMIT = 20;
|
|
814
|
-
var MAX_LIMIT = 100;
|
|
815
|
-
function normalizeText(value) {
|
|
816
|
-
return value?.trim().toLowerCase() ?? "";
|
|
817
|
-
}
|
|
818
|
-
function normalizeRoute(route) {
|
|
819
|
-
const decoded = decodeURIComponent(route).trim();
|
|
820
|
-
if (!decoded)
|
|
821
|
-
return "/";
|
|
822
|
-
return decoded.startsWith("/") ? decoded : `/${decoded}`;
|
|
823
|
-
}
|
|
824
|
-
function normalizeTags(value) {
|
|
825
|
-
const tags = Array.isArray(value) ? value : value ? [value] : [];
|
|
826
|
-
return tags.map((tag) => normalizeText(tag)).filter(Boolean);
|
|
827
|
-
}
|
|
828
|
-
function clampLimit(limit) {
|
|
829
|
-
if (!limit || Number.isNaN(limit))
|
|
830
|
-
return DEFAULT_LIMIT;
|
|
831
|
-
return Math.min(Math.max(limit, 1), MAX_LIMIT);
|
|
832
|
-
}
|
|
833
|
-
function clampOffset(offset) {
|
|
834
|
-
if (!offset || Number.isNaN(offset))
|
|
835
|
-
return 0;
|
|
836
|
-
return Math.max(offset, 0);
|
|
837
|
-
}
|
|
838
|
-
function toDocSummary({ block, route }) {
|
|
839
|
-
return {
|
|
840
|
-
id: block.id,
|
|
841
|
-
title: block.title,
|
|
842
|
-
summary: block.summary ?? "",
|
|
843
|
-
route,
|
|
844
|
-
visibility: block.visibility ?? "public",
|
|
845
|
-
kind: block.kind ?? "reference",
|
|
846
|
-
version: block.version ?? "1.0.0",
|
|
847
|
-
tags: block.tags ?? []
|
|
848
|
-
};
|
|
849
|
-
}
|
|
850
|
-
function scoreDoc(route, query) {
|
|
851
|
-
if (!query)
|
|
852
|
-
return 1;
|
|
853
|
-
const tokens = query.split(/\s+/).filter(Boolean);
|
|
854
|
-
const title = normalizeText(route.block.title);
|
|
855
|
-
const id = normalizeText(route.block.id);
|
|
856
|
-
const summary = normalizeText(route.block.summary);
|
|
857
|
-
const body = normalizeText(route.block.body);
|
|
858
|
-
const path2 = normalizeText(route.route);
|
|
859
|
-
const tags = (route.block.tags ?? []).map((tag) => normalizeText(tag));
|
|
860
|
-
const haystack = [title, id, summary, body, path2, ...tags].join(" ");
|
|
861
|
-
if (tokens.some((token) => !haystack.includes(token)))
|
|
862
|
-
return 0;
|
|
863
|
-
let score = 0;
|
|
864
|
-
for (const token of tokens) {
|
|
865
|
-
if (id.includes(token))
|
|
866
|
-
score += 8;
|
|
867
|
-
if (title.includes(token))
|
|
868
|
-
score += 7;
|
|
869
|
-
if (tags.some((tag) => tag.includes(token)))
|
|
870
|
-
score += 5;
|
|
871
|
-
if (summary.includes(token))
|
|
872
|
-
score += 4;
|
|
873
|
-
if (path2.includes(token))
|
|
874
|
-
score += 3;
|
|
875
|
-
if (body.includes(token))
|
|
876
|
-
score += 2;
|
|
877
|
-
}
|
|
878
|
-
return score;
|
|
879
|
-
}
|
|
880
|
-
function searchDocs(routes, args) {
|
|
881
|
-
const query = normalizeText(typeof args.query === "string" ? args.query : undefined);
|
|
882
|
-
const tags = normalizeTags(args.tag);
|
|
883
|
-
const visibility = normalizeText(typeof args.visibility === "string" ? args.visibility : undefined);
|
|
884
|
-
const kind = normalizeText(typeof args.kind === "string" ? args.kind : undefined);
|
|
885
|
-
const limit = clampLimit(typeof args.limit === "number" ? args.limit : undefined);
|
|
886
|
-
const offset = clampOffset(typeof args.offset === "number" ? args.offset : undefined);
|
|
887
|
-
const ranked = routes.map((route) => ({
|
|
888
|
-
doc: toDocSummary(route),
|
|
889
|
-
score: scoreDoc(route, query)
|
|
890
|
-
})).filter(({ doc, score }) => {
|
|
891
|
-
const matchesQuery = query ? score > 0 : true;
|
|
892
|
-
const matchesTags = tags.length ? tags.every((tag) => doc.tags.some((docTag) => normalizeText(docTag).includes(tag))) : true;
|
|
893
|
-
const matchesVisibility = visibility ? normalizeText(doc.visibility) === visibility : true;
|
|
894
|
-
const matchesKind = kind ? normalizeText(doc.kind) === kind : true;
|
|
895
|
-
return matchesQuery && matchesTags && matchesVisibility && matchesKind;
|
|
896
|
-
}).sort((left, right) => {
|
|
897
|
-
if (right.score !== left.score)
|
|
898
|
-
return right.score - left.score;
|
|
899
|
-
return left.doc.title.localeCompare(right.doc.title);
|
|
900
|
-
});
|
|
901
|
-
const docs = ranked.slice(offset, offset + limit).map(({ doc }) => doc);
|
|
902
|
-
const nextOffset = offset + docs.length < ranked.length ? offset + docs.length : undefined;
|
|
903
|
-
return {
|
|
904
|
-
docs,
|
|
905
|
-
items: docs,
|
|
906
|
-
total: ranked.length,
|
|
907
|
-
...nextOffset != null ? { nextOffset } : {}
|
|
908
|
-
};
|
|
909
|
-
}
|
|
910
|
-
function getDocById(id) {
|
|
911
|
-
const normalizedId = decodeURIComponent(id);
|
|
912
|
-
const found = defaultDocRegistry.get(normalizedId);
|
|
913
|
-
if (!found)
|
|
914
|
-
return;
|
|
915
|
-
return {
|
|
916
|
-
doc: toDocSummary(found),
|
|
917
|
-
content: String(found.block.body ?? "")
|
|
918
|
-
};
|
|
919
|
-
}
|
|
920
|
-
function getDocByRoute(routes, routePath) {
|
|
921
|
-
const normalizedPath = normalizeRoute(routePath);
|
|
922
|
-
const found = routes.find((route) => normalizeRoute(route.route) === normalizedPath);
|
|
923
|
-
if (!found)
|
|
924
|
-
return;
|
|
925
|
-
return {
|
|
926
|
-
doc: toDocSummary(found),
|
|
927
|
-
content: String(found.block.body ?? "")
|
|
928
|
-
};
|
|
929
|
-
}
|
|
930
|
-
function listDocFacets(routes) {
|
|
931
|
-
const tags = new Map;
|
|
932
|
-
const kinds = new Map;
|
|
933
|
-
const visibilities = new Map;
|
|
934
|
-
for (const route of routes) {
|
|
935
|
-
const kind = route.block.kind ?? "reference";
|
|
936
|
-
const visibility = route.block.visibility ?? "public";
|
|
937
|
-
kinds.set(kind, (kinds.get(kind) ?? 0) + 1);
|
|
938
|
-
visibilities.set(visibility, (visibilities.get(visibility) ?? 0) + 1);
|
|
939
|
-
for (const tag of route.block.tags ?? []) {
|
|
940
|
-
tags.set(tag, (tags.get(tag) ?? 0) + 1);
|
|
941
|
-
}
|
|
942
|
-
}
|
|
943
|
-
const toEntries = (values, key) => [...values.entries()].sort((left, right) => right[1] - left[1] || left[0].localeCompare(right[0])).map(([value, count]) => ({ [key]: value, count }));
|
|
944
|
-
return {
|
|
945
|
-
totalDocs: routes.length,
|
|
946
|
-
tags: toEntries(tags, "tag"),
|
|
947
|
-
kinds: toEntries(kinds, "kind"),
|
|
948
|
-
visibilities: toEntries(visibilities, "visibility")
|
|
949
|
-
};
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
// src/features/contracts-registry.ts
|
|
953
|
-
import {
|
|
954
|
-
EventRegistry,
|
|
955
|
-
OperationSpecRegistry as OperationSpecRegistry3
|
|
956
|
-
} from "@contractspec/lib.contracts-spec";
|
|
957
|
-
import {
|
|
958
|
-
DataViewRegistry
|
|
959
|
-
} from "@contractspec/lib.contracts-spec/data-views";
|
|
960
|
-
import {
|
|
961
|
-
ContractReferenceDataView,
|
|
962
|
-
ContractReferenceQuery,
|
|
963
|
-
DocsGenerateCommand,
|
|
964
|
-
DocsGeneratedEvent,
|
|
965
|
-
DocsIndexDataView,
|
|
966
|
-
DocsIndexQuery,
|
|
967
|
-
DocsLayoutPresentation,
|
|
968
|
-
DocsPublishCommand,
|
|
969
|
-
DocsPublishedEvent,
|
|
970
|
-
DocsReferencePagePresentation,
|
|
971
|
-
DocsSearchForm,
|
|
972
|
-
ExampleCatalogDataView
|
|
973
|
-
} from "@contractspec/lib.contracts-spec/docs";
|
|
974
|
-
import { FormRegistry } from "@contractspec/lib.contracts-spec/forms";
|
|
975
|
-
import {
|
|
976
|
-
PresentationRegistry as PresentationRegistry2
|
|
977
|
-
} from "@contractspec/lib.contracts-spec/presentations";
|
|
978
|
-
import {
|
|
979
|
-
serializeDataViewSpec,
|
|
980
|
-
serializeEventSpec,
|
|
981
|
-
serializeFormSpec,
|
|
982
|
-
serializeOperationSpec,
|
|
983
|
-
serializePresentationSpec
|
|
984
|
-
} from "@contractspec/lib.contracts-spec/serialization";
|
|
985
|
-
var operationRegistry = null;
|
|
986
|
-
function createContractSpecOperationRegistry() {
|
|
987
|
-
const registry = new OperationSpecRegistry3;
|
|
988
|
-
registry.register(DocsIndexQuery).register(ContractReferenceQuery).register(DocsGenerateCommand).register(DocsPublishCommand);
|
|
989
|
-
return registry;
|
|
990
|
-
}
|
|
991
|
-
function getContractSpecOperationRegistry() {
|
|
992
|
-
if (!operationRegistry) {
|
|
993
|
-
operationRegistry = createContractSpecOperationRegistry();
|
|
994
|
-
}
|
|
995
|
-
return operationRegistry;
|
|
996
|
-
}
|
|
997
|
-
function resolveOperationSpec(key, version) {
|
|
998
|
-
return getContractSpecOperationRegistry().get(key, version);
|
|
999
|
-
}
|
|
1000
|
-
var eventRegistry = null;
|
|
1001
|
-
function createContractSpecEventRegistry() {
|
|
1002
|
-
const registry = new EventRegistry;
|
|
1003
|
-
registry.register(DocsGeneratedEvent).register(DocsPublishedEvent);
|
|
1004
|
-
return registry;
|
|
1005
|
-
}
|
|
1006
|
-
function getContractSpecEventRegistry() {
|
|
1007
|
-
if (!eventRegistry) {
|
|
1008
|
-
eventRegistry = createContractSpecEventRegistry();
|
|
1009
|
-
}
|
|
1010
|
-
return eventRegistry;
|
|
1011
|
-
}
|
|
1012
|
-
function resolveEventSpec(key, version) {
|
|
1013
|
-
return getContractSpecEventRegistry().get(key, version);
|
|
1014
|
-
}
|
|
1015
|
-
var presentationRegistry = null;
|
|
1016
|
-
function createContractSpecPresentationRegistry() {
|
|
1017
|
-
const registry = new PresentationRegistry2;
|
|
1018
|
-
registry.register(DocsLayoutPresentation).register(DocsReferencePagePresentation);
|
|
1019
|
-
return registry;
|
|
1020
|
-
}
|
|
1021
|
-
function getContractSpecPresentationRegistry() {
|
|
1022
|
-
if (!presentationRegistry) {
|
|
1023
|
-
presentationRegistry = createContractSpecPresentationRegistry();
|
|
1024
|
-
}
|
|
1025
|
-
return presentationRegistry;
|
|
1026
|
-
}
|
|
1027
|
-
function resolvePresentationSpec(key, version) {
|
|
1028
|
-
return getContractSpecPresentationRegistry().get(key, version);
|
|
1029
|
-
}
|
|
1030
|
-
var dataViewRegistry = null;
|
|
1031
|
-
function createContractSpecDataViewRegistry() {
|
|
1032
|
-
const registry = new DataViewRegistry;
|
|
1033
|
-
registry.register(DocsIndexDataView).register(ContractReferenceDataView).register(ExampleCatalogDataView);
|
|
1034
|
-
return registry;
|
|
1035
|
-
}
|
|
1036
|
-
function getContractSpecDataViewRegistry() {
|
|
1037
|
-
if (!dataViewRegistry) {
|
|
1038
|
-
dataViewRegistry = createContractSpecDataViewRegistry();
|
|
1039
|
-
}
|
|
1040
|
-
return dataViewRegistry;
|
|
1041
|
-
}
|
|
1042
|
-
function resolveDataViewSpec(key, version) {
|
|
1043
|
-
return getContractSpecDataViewRegistry().get(key, version);
|
|
1044
|
-
}
|
|
1045
|
-
var formRegistry = null;
|
|
1046
|
-
function createContractSpecFormRegistry() {
|
|
1047
|
-
const registry = new FormRegistry;
|
|
1048
|
-
registry.register(DocsSearchForm);
|
|
1049
|
-
return registry;
|
|
1050
|
-
}
|
|
1051
|
-
function getContractSpecFormRegistry() {
|
|
1052
|
-
if (!formRegistry) {
|
|
1053
|
-
formRegistry = createContractSpecFormRegistry();
|
|
1054
|
-
}
|
|
1055
|
-
return formRegistry;
|
|
1056
|
-
}
|
|
1057
|
-
function resolveFormSpec(key, _version) {
|
|
1058
|
-
return getContractSpecFormRegistry().get(key);
|
|
1059
|
-
}
|
|
1060
|
-
function resolveSerializedOperationSpec(key, version) {
|
|
1061
|
-
const spec = resolveOperationSpec(key, version);
|
|
1062
|
-
return serializeOperationSpec(spec) ?? undefined;
|
|
1063
|
-
}
|
|
1064
|
-
function resolveSerializedEventSpec(key, version) {
|
|
1065
|
-
const spec = resolveEventSpec(key, version);
|
|
1066
|
-
return serializeEventSpec(spec) ?? undefined;
|
|
1067
|
-
}
|
|
1068
|
-
function resolveSerializedPresentationSpec(key, version) {
|
|
1069
|
-
const spec = resolvePresentationSpec(key, version);
|
|
1070
|
-
return serializePresentationSpec(spec) ?? undefined;
|
|
1071
|
-
}
|
|
1072
|
-
function resolveSerializedDataViewSpec(key, version) {
|
|
1073
|
-
const spec = resolveDataViewSpec(key, version);
|
|
1074
|
-
return serializeDataViewSpec(spec) ?? undefined;
|
|
1075
|
-
}
|
|
1076
|
-
function resolveSerializedFormSpec(key, version) {
|
|
1077
|
-
const spec = resolveFormSpec(key, version);
|
|
1078
|
-
return serializeFormSpec(spec) ?? undefined;
|
|
1079
|
-
}
|
|
1080
|
-
function resetContractSpecOperationRegistry() {
|
|
1081
|
-
operationRegistry = null;
|
|
1082
|
-
}
|
|
1083
|
-
function resetContractSpecEventRegistry() {
|
|
1084
|
-
eventRegistry = null;
|
|
1085
|
-
}
|
|
1086
|
-
function resetContractSpecPresentationRegistry() {
|
|
1087
|
-
presentationRegistry = null;
|
|
1088
|
-
}
|
|
1089
|
-
function resetContractSpecDataViewRegistry() {
|
|
1090
|
-
dataViewRegistry = null;
|
|
1091
|
-
}
|
|
1092
|
-
function resetContractSpecFormRegistry() {
|
|
1093
|
-
formRegistry = null;
|
|
1094
|
-
}
|
|
1095
|
-
function resetAllContractSpecRegistries() {
|
|
1096
|
-
resetContractSpecOperationRegistry();
|
|
1097
|
-
resetContractSpecEventRegistry();
|
|
1098
|
-
resetContractSpecPresentationRegistry();
|
|
1099
|
-
resetContractSpecDataViewRegistry();
|
|
1100
|
-
resetContractSpecFormRegistry();
|
|
1101
|
-
}
|
|
1102
|
-
|
|
1103
|
-
// src/application/mcp/docsMcp.reference.ts
|
|
1104
|
-
import { defaultDocRegistry as defaultDocRegistry2 } from "@contractspec/lib.contracts-spec/docs";
|
|
1105
|
-
function normalizeText2(value) {
|
|
1106
|
-
return value?.trim().toLowerCase() ?? "";
|
|
1107
|
-
}
|
|
1108
|
-
function routeFromDocIds(docIds) {
|
|
1109
|
-
for (const docId of docIds ?? []) {
|
|
1110
|
-
const doc = defaultDocRegistry2.get(docId);
|
|
1111
|
-
if (doc)
|
|
1112
|
-
return doc.route;
|
|
1113
|
-
}
|
|
1114
|
-
return;
|
|
1115
|
-
}
|
|
1116
|
-
function toReference(spec, type, schema, policy) {
|
|
1117
|
-
const title = spec.meta.title ?? spec.meta.key;
|
|
1118
|
-
const route = routeFromDocIds(spec.meta.docId);
|
|
1119
|
-
const description = spec.meta.description;
|
|
1120
|
-
return {
|
|
1121
|
-
key: spec.meta.key,
|
|
1122
|
-
version: spec.meta.version,
|
|
1123
|
-
type,
|
|
1124
|
-
title,
|
|
1125
|
-
description,
|
|
1126
|
-
markdown: [
|
|
1127
|
-
`# ${title}`,
|
|
1128
|
-
`- Key: ${spec.meta.key}`,
|
|
1129
|
-
`- Type: ${type}`,
|
|
1130
|
-
`- Version: ${spec.meta.version}`,
|
|
1131
|
-
route ? `- Docs route: ${route}` : "",
|
|
1132
|
-
description ? `
|
|
1133
|
-
${description}` : ""
|
|
1134
|
-
].filter(Boolean).join(`
|
|
1135
|
-
`),
|
|
1136
|
-
...route ? { route } : {},
|
|
1137
|
-
...schema ? { schema } : {},
|
|
1138
|
-
...policy ? { policy } : {},
|
|
1139
|
-
tags: spec.meta.tags ?? [],
|
|
1140
|
-
owners: spec.meta.owners ?? [],
|
|
1141
|
-
stability: spec.meta.stability
|
|
1142
|
-
};
|
|
1143
|
-
}
|
|
1144
|
-
function resolveContractReference(args) {
|
|
1145
|
-
const includeSchema = args.includeSchema ?? false;
|
|
1146
|
-
const requestedType = normalizeText2(args.type);
|
|
1147
|
-
const operation = resolveOperationSpec(args.key, args.version);
|
|
1148
|
-
if (operation && (!requestedType || requestedType === "operation" || requestedType === operation.meta.kind)) {
|
|
1149
|
-
return {
|
|
1150
|
-
reference: toReference(operation, operation.meta.kind, includeSchema ? resolveSerializedOperationSpec(args.key, args.version) : undefined, operation.policy)
|
|
1151
|
-
};
|
|
1152
|
-
}
|
|
1153
|
-
const resolvers = [
|
|
1154
|
-
{
|
|
1155
|
-
type: "data-view",
|
|
1156
|
-
spec: resolveDataViewSpec(args.key, args.version),
|
|
1157
|
-
schema: includeSchema ? resolveSerializedDataViewSpec(args.key, args.version) : undefined
|
|
1158
|
-
},
|
|
1159
|
-
{
|
|
1160
|
-
type: "form",
|
|
1161
|
-
spec: resolveFormSpec(args.key, args.version),
|
|
1162
|
-
schema: includeSchema ? resolveSerializedFormSpec(args.key, args.version) : undefined
|
|
1163
|
-
},
|
|
1164
|
-
{
|
|
1165
|
-
type: "presentation",
|
|
1166
|
-
spec: resolvePresentationSpec(args.key, args.version),
|
|
1167
|
-
schema: includeSchema ? resolveSerializedPresentationSpec(args.key, args.version) : undefined
|
|
1168
|
-
},
|
|
1169
|
-
{
|
|
1170
|
-
type: "event",
|
|
1171
|
-
spec: resolveEventSpec(args.key, args.version),
|
|
1172
|
-
schema: includeSchema ? resolveSerializedEventSpec(args.key, args.version) : undefined
|
|
1173
|
-
}
|
|
1174
|
-
];
|
|
1175
|
-
for (const candidate of resolvers) {
|
|
1176
|
-
if (candidate.spec && (!requestedType || requestedType === candidate.type)) {
|
|
1177
|
-
return {
|
|
1178
|
-
reference: toReference(candidate.spec, candidate.type, candidate.schema)
|
|
1179
|
-
};
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
throw new Error(`Contract reference not found: ${args.key}`);
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
|
-
// src/application/mcp/docsMcp.prompts.ts
|
|
1186
|
-
import { definePrompt as definePrompt3, PromptRegistry as PromptRegistry3 } from "@contractspec/lib.contracts-spec";
|
|
1187
|
-
import z3 from "zod";
|
|
1188
|
-
var DOC_OWNERS = ["@contractspec"];
|
|
1189
|
-
var DOC_TAGS = ["docs", "mcp"];
|
|
1190
|
-
function buildDocPrompts(routes) {
|
|
1191
|
-
const prompts = new PromptRegistry3;
|
|
1192
|
-
prompts.register(definePrompt3({
|
|
1193
|
-
meta: {
|
|
1194
|
-
key: "docs.navigator",
|
|
1195
|
-
version: "1.0.0",
|
|
1196
|
-
title: "Find relevant ContractSpec docs",
|
|
1197
|
-
description: "Guide agents to search, filter, and open the right ContractSpec docs.",
|
|
1198
|
-
tags: DOC_TAGS,
|
|
1199
|
-
stability: "beta",
|
|
1200
|
-
owners: DOC_OWNERS
|
|
1201
|
-
},
|
|
1202
|
-
args: [
|
|
1203
|
-
{
|
|
1204
|
-
name: "topic",
|
|
1205
|
-
description: "Goal or subject to search for.",
|
|
1206
|
-
required: false,
|
|
1207
|
-
schema: z3.string().optional()
|
|
1208
|
-
},
|
|
1209
|
-
{
|
|
1210
|
-
name: "kind",
|
|
1211
|
-
description: "Optional doc kind filter.",
|
|
1212
|
-
required: false,
|
|
1213
|
-
schema: z3.string().optional()
|
|
1214
|
-
},
|
|
1215
|
-
{
|
|
1216
|
-
name: "tag",
|
|
1217
|
-
description: "Optional tag filter.",
|
|
1218
|
-
required: false,
|
|
1219
|
-
schema: z3.string().optional()
|
|
1220
|
-
}
|
|
1221
|
-
],
|
|
1222
|
-
input: z3.object({
|
|
1223
|
-
topic: z3.string().optional(),
|
|
1224
|
-
kind: z3.string().optional(),
|
|
1225
|
-
tag: z3.string().optional()
|
|
1226
|
-
}),
|
|
1227
|
-
render: async ({ topic, kind, tag }) => {
|
|
1228
|
-
const matches = searchDocs(routes, {
|
|
1229
|
-
query: topic,
|
|
1230
|
-
kind,
|
|
1231
|
-
tag,
|
|
1232
|
-
limit: 3
|
|
1233
|
-
});
|
|
1234
|
-
const suggestedDocs = matches.docs.length ? matches.docs.map((doc) => `- ${doc.title} (${doc.id}) -> ${doc.route}`).join(`
|
|
1235
|
-
`) : "- No direct pre-match. Use docs_list_facets-v1_0_0 to browse tags and kinds.";
|
|
1236
|
-
return [
|
|
1237
|
-
{
|
|
1238
|
-
type: "text",
|
|
1239
|
-
text: [
|
|
1240
|
-
"Use docs_search-v1_0_0 first, then read docs://doc/{id} for the strongest matches.",
|
|
1241
|
-
"Use docs_resolve_route-v1_0_0 when the user already gives you a docs URL or route.",
|
|
1242
|
-
"Use docs_list_facets-v1_0_0 or docs://facets to browse the docs taxonomy before guessing.",
|
|
1243
|
-
topic ? `Topic: ${topic}` : "",
|
|
1244
|
-
kind ? `Kind: ${kind}` : "",
|
|
1245
|
-
tag ? `Tag: ${tag}` : "",
|
|
1246
|
-
"Suggested starting docs:",
|
|
1247
|
-
suggestedDocs
|
|
1248
|
-
].filter(Boolean).join(`
|
|
1249
|
-
`)
|
|
1250
|
-
},
|
|
1251
|
-
{
|
|
1252
|
-
type: "resource",
|
|
1253
|
-
uri: "docs://index",
|
|
1254
|
-
title: "DocBlocks index"
|
|
1255
|
-
},
|
|
1256
|
-
{
|
|
1257
|
-
type: "resource",
|
|
1258
|
-
uri: "docs://facets",
|
|
1259
|
-
title: "Docs facets"
|
|
1260
|
-
}
|
|
1261
|
-
];
|
|
1262
|
-
}
|
|
1263
|
-
}));
|
|
1264
|
-
prompts.register(definePrompt3({
|
|
1265
|
-
meta: {
|
|
1266
|
-
key: "docs.reference.guide",
|
|
1267
|
-
version: "1.0.0",
|
|
1268
|
-
title: "Resolve a ContractSpec reference",
|
|
1269
|
-
description: "Guide agents to fetch the canonical reference payload for a ContractSpec surface.",
|
|
1270
|
-
tags: DOC_TAGS,
|
|
1271
|
-
stability: "beta",
|
|
1272
|
-
owners: DOC_OWNERS
|
|
1273
|
-
},
|
|
1274
|
-
args: [
|
|
1275
|
-
{
|
|
1276
|
-
name: "key",
|
|
1277
|
-
description: "ContractSpec key to resolve.",
|
|
1278
|
-
required: true,
|
|
1279
|
-
schema: z3.string()
|
|
1280
|
-
},
|
|
1281
|
-
{
|
|
1282
|
-
name: "version",
|
|
1283
|
-
description: "Optional version override.",
|
|
1284
|
-
required: false,
|
|
1285
|
-
schema: z3.string().optional()
|
|
1286
|
-
},
|
|
1287
|
-
{
|
|
1288
|
-
name: "type",
|
|
1289
|
-
description: "Optional surface type: command, query, form, data-view, presentation, event.",
|
|
1290
|
-
required: false,
|
|
1291
|
-
schema: z3.string().optional()
|
|
1292
|
-
}
|
|
1293
|
-
],
|
|
1294
|
-
input: z3.object({
|
|
1295
|
-
key: z3.string(),
|
|
1296
|
-
version: z3.string().optional(),
|
|
1297
|
-
type: z3.string().optional()
|
|
1298
|
-
}),
|
|
1299
|
-
render: async ({ key, version, type }) => {
|
|
1300
|
-
const reference = resolveContractReference({
|
|
1301
|
-
key,
|
|
1302
|
-
version,
|
|
1303
|
-
type,
|
|
1304
|
-
includeSchema: true
|
|
1305
|
-
}).reference;
|
|
1306
|
-
return [
|
|
1307
|
-
{
|
|
1308
|
-
type: "text",
|
|
1309
|
-
text: [
|
|
1310
|
-
"Use docs_contract_reference-v1_0_0 when you need the canonical docs payload for a ContractSpec surface.",
|
|
1311
|
-
"Use docs_get-v1_0_0 only when you already know the exact DocBlock id and need raw markdown.",
|
|
1312
|
-
`Resolved key: ${reference.key}`,
|
|
1313
|
-
`Resolved type: ${reference.type}`,
|
|
1314
|
-
reference.route ? `Docs route: ${reference.route}` : "",
|
|
1315
|
-
`Resource URI: docs://contract-reference/${encodeURIComponent(key)}`
|
|
1316
|
-
].filter(Boolean).join(`
|
|
1317
|
-
`)
|
|
1318
|
-
},
|
|
1319
|
-
{
|
|
1320
|
-
type: "resource",
|
|
1321
|
-
uri: `docs://contract-reference/${encodeURIComponent(key)}`,
|
|
1322
|
-
title: "Contract reference"
|
|
1323
|
-
}
|
|
1324
|
-
];
|
|
1325
|
-
}
|
|
1326
|
-
}));
|
|
1327
|
-
return prompts;
|
|
1328
|
-
}
|
|
1329
|
-
|
|
1330
|
-
// src/application/mcp/docsMcp.resources.ts
|
|
1331
|
-
import {
|
|
1332
|
-
defineResourceTemplate as defineResourceTemplate3,
|
|
1333
|
-
ResourceRegistry as ResourceRegistry3
|
|
1334
|
-
} from "@contractspec/lib.contracts-spec";
|
|
1335
|
-
import z4 from "zod";
|
|
1336
|
-
var DOC_TAGS2 = ["docs", "mcp"];
|
|
1337
|
-
function buildDocResources(routes) {
|
|
1338
|
-
const resources = new ResourceRegistry3;
|
|
1339
|
-
const readDocIndex = (input) => searchDocs(routes, input);
|
|
1340
|
-
resources.register(defineResourceTemplate3({
|
|
1341
|
-
meta: {
|
|
1342
|
-
uriTemplate: "docs://index",
|
|
1343
|
-
title: "DocBlocks index",
|
|
1344
|
-
description: "Default ContractSpec docs index resource.",
|
|
1345
|
-
mimeType: "application/json",
|
|
1346
|
-
tags: DOC_TAGS2
|
|
1347
|
-
},
|
|
1348
|
-
input: z4.object({}),
|
|
1349
|
-
resolve: async () => ({
|
|
1350
|
-
uri: "docs://index",
|
|
1351
|
-
mimeType: "application/json",
|
|
1352
|
-
data: JSON.stringify(readDocIndex({}), null, 2)
|
|
1353
|
-
})
|
|
1354
|
-
}));
|
|
1355
|
-
resources.register(defineResourceTemplate3({
|
|
1356
|
-
meta: {
|
|
1357
|
-
uriTemplate: "docs://index{?query,tag,kind,visibility,limit,offset}",
|
|
1358
|
-
title: "DocBlocks index",
|
|
1359
|
-
description: "Search and paginate ContractSpec docs by query, tag, kind, or visibility.",
|
|
1360
|
-
mimeType: "application/json",
|
|
1361
|
-
tags: DOC_TAGS2
|
|
1362
|
-
},
|
|
1363
|
-
input: z4.object({
|
|
1364
|
-
query: z4.string().optional(),
|
|
1365
|
-
tag: z4.string().optional(),
|
|
1366
|
-
kind: z4.string().optional(),
|
|
1367
|
-
visibility: z4.string().optional(),
|
|
1368
|
-
limit: z4.coerce.number().optional(),
|
|
1369
|
-
offset: z4.coerce.number().optional()
|
|
1370
|
-
}),
|
|
1371
|
-
resolve: async (input) => ({
|
|
1372
|
-
uri: "docs://index",
|
|
1373
|
-
mimeType: "application/json",
|
|
1374
|
-
data: JSON.stringify(readDocIndex(input), null, 2)
|
|
1375
|
-
})
|
|
1376
|
-
}));
|
|
1377
|
-
resources.register(defineResourceTemplate3({
|
|
1378
|
-
meta: {
|
|
1379
|
-
uriTemplate: "docs://list",
|
|
1380
|
-
title: "DocBlocks index (legacy alias)",
|
|
1381
|
-
description: "Compatibility alias for the docs index resource.",
|
|
1382
|
-
mimeType: "application/json",
|
|
1383
|
-
tags: DOC_TAGS2
|
|
1384
|
-
},
|
|
1385
|
-
input: z4.object({}),
|
|
1386
|
-
resolve: async () => ({
|
|
1387
|
-
uri: "docs://list",
|
|
1388
|
-
mimeType: "application/json",
|
|
1389
|
-
data: JSON.stringify(readDocIndex({}), null, 2)
|
|
1390
|
-
})
|
|
1391
|
-
}));
|
|
1392
|
-
resources.register(defineResourceTemplate3({
|
|
1393
|
-
meta: {
|
|
1394
|
-
uriTemplate: "docs://doc/{id}",
|
|
1395
|
-
title: "Doc markdown",
|
|
1396
|
-
description: "Fetch a single DocBlock body by id as markdown.",
|
|
1397
|
-
mimeType: "text/markdown",
|
|
1398
|
-
tags: DOC_TAGS2
|
|
1399
|
-
},
|
|
1400
|
-
input: z4.object({ id: z4.string() }),
|
|
1401
|
-
resolve: async ({ id }) => {
|
|
1402
|
-
const found = getDocById(id);
|
|
1403
|
-
if (!found) {
|
|
1404
|
-
return {
|
|
1405
|
-
uri: `docs://doc/${encodeURIComponent(id)}`,
|
|
1406
|
-
mimeType: "text/plain",
|
|
1407
|
-
data: `DocBlock not found: ${id}`
|
|
1408
|
-
};
|
|
1409
|
-
}
|
|
1410
|
-
return {
|
|
1411
|
-
uri: `docs://doc/${encodeURIComponent(id)}`,
|
|
1412
|
-
mimeType: "text/markdown",
|
|
1413
|
-
data: found.content
|
|
1414
|
-
};
|
|
1415
|
-
}
|
|
1416
|
-
}));
|
|
1417
|
-
resources.register(defineResourceTemplate3({
|
|
1418
|
-
meta: {
|
|
1419
|
-
uriTemplate: "docs://route/{routePath}",
|
|
1420
|
-
title: "Doc by route",
|
|
1421
|
-
description: "Resolve a docs route to the matching DocBlock summary and body.",
|
|
1422
|
-
mimeType: "application/json",
|
|
1423
|
-
tags: DOC_TAGS2
|
|
1424
|
-
},
|
|
1425
|
-
input: z4.object({ routePath: z4.string() }),
|
|
1426
|
-
resolve: async ({ routePath }) => ({
|
|
1427
|
-
uri: `docs://route/${encodeURIComponent(routePath)}`,
|
|
1428
|
-
mimeType: "application/json",
|
|
1429
|
-
data: JSON.stringify(getDocByRoute(routes, routePath) ?? {
|
|
1430
|
-
error: "not_found",
|
|
1431
|
-
route: routePath
|
|
1432
|
-
}, null, 2)
|
|
1433
|
-
})
|
|
1434
|
-
}));
|
|
1435
|
-
resources.register(defineResourceTemplate3({
|
|
1436
|
-
meta: {
|
|
1437
|
-
uriTemplate: "docs://facets",
|
|
1438
|
-
title: "Docs facets",
|
|
1439
|
-
description: "Counts of available tags, kinds, and visibilities across docs.",
|
|
1440
|
-
mimeType: "application/json",
|
|
1441
|
-
tags: DOC_TAGS2
|
|
1442
|
-
},
|
|
1443
|
-
input: z4.object({}),
|
|
1444
|
-
resolve: async () => ({
|
|
1445
|
-
uri: "docs://facets",
|
|
1446
|
-
mimeType: "application/json",
|
|
1447
|
-
data: JSON.stringify(listDocFacets(routes), null, 2)
|
|
1448
|
-
})
|
|
1449
|
-
}));
|
|
1450
|
-
resources.register(defineResourceTemplate3({
|
|
1451
|
-
meta: {
|
|
1452
|
-
uriTemplate: "docs://contract-reference/{key}{?version,type,includeSchema}",
|
|
1453
|
-
title: "Contract reference",
|
|
1454
|
-
description: "Resolve a ContractSpec surface into a docs-ready reference payload.",
|
|
1455
|
-
mimeType: "application/json",
|
|
1456
|
-
tags: DOC_TAGS2
|
|
1457
|
-
},
|
|
1458
|
-
input: z4.object({
|
|
1459
|
-
key: z4.string(),
|
|
1460
|
-
version: z4.string().optional(),
|
|
1461
|
-
type: z4.string().optional(),
|
|
1462
|
-
includeSchema: z4.coerce.boolean().optional()
|
|
1463
|
-
}),
|
|
1464
|
-
resolve: async ({ key, version, type, includeSchema }) => ({
|
|
1465
|
-
uri: `docs://contract-reference/${encodeURIComponent(key)}`,
|
|
1466
|
-
mimeType: "application/json",
|
|
1467
|
-
data: JSON.stringify(resolveContractReference({ key, version, type, includeSchema }), null, 2)
|
|
1468
|
-
})
|
|
1469
|
-
}));
|
|
1470
|
-
return resources;
|
|
1471
|
-
}
|
|
1472
|
-
|
|
1473
|
-
// src/application/mcp/docsMcp.tools.ts
|
|
1474
|
-
import {
|
|
1475
|
-
defineCommand as defineCommand3,
|
|
1476
|
-
defineSchemaModel as defineSchemaModel3,
|
|
1477
|
-
installOp as installOp3,
|
|
1478
|
-
OperationSpecRegistry as OperationSpecRegistry4
|
|
1479
|
-
} from "@contractspec/lib.contracts-spec";
|
|
1480
|
-
import {
|
|
1481
|
-
ContractReferenceInput,
|
|
1482
|
-
ContractReferenceOutput,
|
|
1483
|
-
DocsIndexInput,
|
|
1484
|
-
DocsIndexOutput
|
|
1485
|
-
} from "@contractspec/lib.contracts-spec/docs";
|
|
1486
|
-
import { ScalarTypeEnum as ScalarTypeEnum3 } from "@contractspec/lib.schema";
|
|
1487
|
-
var DOC_OWNERS2 = ["@contractspec"];
|
|
1488
|
-
var DOC_TAGS3 = ["docs", "mcp"];
|
|
1489
|
-
var DocsGetInput = defineSchemaModel3({
|
|
1490
|
-
name: "DocsGetInput",
|
|
1491
|
-
fields: {
|
|
1492
|
-
id: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false }
|
|
1493
|
-
}
|
|
1494
|
-
});
|
|
1495
|
-
var DocsGetOutput = defineSchemaModel3({
|
|
1496
|
-
name: "DocsGetOutput",
|
|
1497
|
-
fields: {
|
|
1498
|
-
doc: { type: ScalarTypeEnum3.JSON(), isOptional: false },
|
|
1499
|
-
content: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false }
|
|
1500
|
-
}
|
|
1501
|
-
});
|
|
1502
|
-
var DocsResolveRouteInput = defineSchemaModel3({
|
|
1503
|
-
name: "DocsResolveRouteInput",
|
|
1504
|
-
fields: {
|
|
1505
|
-
route: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false }
|
|
1506
|
-
}
|
|
1507
|
-
});
|
|
1508
|
-
var DocsResolveRouteOutput = defineSchemaModel3({
|
|
1509
|
-
name: "DocsResolveRouteOutput",
|
|
1510
|
-
fields: {
|
|
1511
|
-
doc: { type: ScalarTypeEnum3.JSON(), isOptional: false },
|
|
1512
|
-
content: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false }
|
|
1513
|
-
}
|
|
1514
|
-
});
|
|
1515
|
-
var DocsFacetsInput = defineSchemaModel3({
|
|
1516
|
-
name: "DocsFacetsInput",
|
|
1517
|
-
fields: {}
|
|
1518
|
-
});
|
|
1519
|
-
var DocsFacetsOutput = defineSchemaModel3({
|
|
1520
|
-
name: "DocsFacetsOutput",
|
|
1521
|
-
fields: {
|
|
1522
|
-
facets: { type: ScalarTypeEnum3.JSON(), isOptional: false }
|
|
1523
|
-
}
|
|
1524
|
-
});
|
|
1525
|
-
function buildDocOps(routes) {
|
|
1526
|
-
const registry = new OperationSpecRegistry4;
|
|
1527
|
-
installOp3(registry, defineCommand3({
|
|
1528
|
-
meta: {
|
|
1529
|
-
key: "docs.search",
|
|
1530
|
-
version: "1.0.0",
|
|
1531
|
-
stability: "beta",
|
|
1532
|
-
owners: DOC_OWNERS2,
|
|
1533
|
-
tags: DOC_TAGS3,
|
|
1534
|
-
description: "Search ContractSpec docs by query, tag, kind, or visibility.",
|
|
1535
|
-
goal: "Find the most relevant DocBlocks without browsing the full corpus.",
|
|
1536
|
-
context: "Read-only docs MCP search surface."
|
|
1537
|
-
},
|
|
1538
|
-
io: { input: DocsIndexInput, output: DocsIndexOutput },
|
|
1539
|
-
policy: { auth: "anonymous" },
|
|
1540
|
-
transport: { mcp: { toolName: "docs_search-v1_0_0" } }
|
|
1541
|
-
}), async (args) => searchDocs(routes, args));
|
|
1542
|
-
installOp3(registry, defineCommand3({
|
|
1543
|
-
meta: {
|
|
1544
|
-
key: "docs.get",
|
|
1545
|
-
version: "1.0.0",
|
|
1546
|
-
stability: "beta",
|
|
1547
|
-
owners: DOC_OWNERS2,
|
|
1548
|
-
tags: DOC_TAGS3,
|
|
1549
|
-
description: "Read a single DocBlock by id.",
|
|
1550
|
-
goal: "Fetch the exact markdown content and metadata for a known doc id.",
|
|
1551
|
-
context: "Read-only docs MCP surface."
|
|
1552
|
-
},
|
|
1553
|
-
io: { input: DocsGetInput, output: DocsGetOutput },
|
|
1554
|
-
policy: { auth: "anonymous" },
|
|
1555
|
-
transport: { mcp: { toolName: "docs_get-v1_0_0" } }
|
|
1556
|
-
}), async ({ id }) => {
|
|
1557
|
-
const found = getDocById(id);
|
|
1558
|
-
if (!found)
|
|
1559
|
-
throw new Error(`DocBlock not found: ${id}`);
|
|
1560
|
-
return found;
|
|
1561
|
-
});
|
|
1562
|
-
installOp3(registry, defineCommand3({
|
|
1563
|
-
meta: {
|
|
1564
|
-
key: "docs.resolveRoute",
|
|
1565
|
-
version: "1.0.0",
|
|
1566
|
-
stability: "beta",
|
|
1567
|
-
owners: DOC_OWNERS2,
|
|
1568
|
-
tags: DOC_TAGS3,
|
|
1569
|
-
description: "Resolve a docs route to the matching DocBlock.",
|
|
1570
|
-
goal: "Turn a route or URL path into a canonical doc id and markdown body.",
|
|
1571
|
-
context: "Read-only docs MCP surface."
|
|
1572
|
-
},
|
|
1573
|
-
io: { input: DocsResolveRouteInput, output: DocsResolveRouteOutput },
|
|
1574
|
-
policy: { auth: "anonymous" },
|
|
1575
|
-
transport: { mcp: { toolName: "docs_resolve_route-v1_0_0" } }
|
|
1576
|
-
}), async ({ route }) => {
|
|
1577
|
-
const found = getDocByRoute(routes, route);
|
|
1578
|
-
if (!found)
|
|
1579
|
-
throw new Error(`Doc route not found: ${route}`);
|
|
1580
|
-
return found;
|
|
1581
|
-
});
|
|
1582
|
-
installOp3(registry, defineCommand3({
|
|
1583
|
-
meta: {
|
|
1584
|
-
key: "docs.contract.lookup",
|
|
1585
|
-
version: "1.0.0",
|
|
1586
|
-
stability: "beta",
|
|
1587
|
-
owners: DOC_OWNERS2,
|
|
1588
|
-
tags: DOC_TAGS3,
|
|
1589
|
-
description: "Resolve a ContractSpec surface into a docs-ready reference payload.",
|
|
1590
|
-
goal: "Get canonical docs metadata, route, and optional schema for a spec key.",
|
|
1591
|
-
context: "Read-only docs MCP surface."
|
|
1592
|
-
},
|
|
1593
|
-
io: { input: ContractReferenceInput, output: ContractReferenceOutput },
|
|
1594
|
-
policy: { auth: "anonymous" },
|
|
1595
|
-
transport: { mcp: { toolName: "docs_contract_reference-v1_0_0" } }
|
|
1596
|
-
}), async (args) => resolveContractReference(args));
|
|
1597
|
-
installOp3(registry, defineCommand3({
|
|
1598
|
-
meta: {
|
|
1599
|
-
key: "docs.list.facets",
|
|
1600
|
-
version: "1.0.0",
|
|
1601
|
-
stability: "beta",
|
|
1602
|
-
owners: DOC_OWNERS2,
|
|
1603
|
-
tags: DOC_TAGS3,
|
|
1604
|
-
description: "List docs taxonomy facets such as tags, kinds, and visibilities.",
|
|
1605
|
-
goal: "Help agents browse the docs corpus before making targeted reads.",
|
|
1606
|
-
context: "Read-only docs MCP surface."
|
|
1607
|
-
},
|
|
1608
|
-
io: { input: DocsFacetsInput, output: DocsFacetsOutput },
|
|
1609
|
-
policy: { auth: "anonymous" },
|
|
1610
|
-
transport: { mcp: { toolName: "docs_list_facets-v1_0_0" } }
|
|
1611
|
-
}), async () => ({ facets: listDocFacets(routes) }));
|
|
1612
|
-
return registry;
|
|
1613
|
-
}
|
|
1614
|
-
|
|
1615
|
-
// src/application/mcp/docsMcp.ts
|
|
1616
|
-
import { defaultDocRegistry as defaultDocRegistry3 } from "@contractspec/lib.contracts-spec/docs";
|
|
1617
|
-
function createDocsMcpHandler(path2 = "/api/mcp/docs", options = {}) {
|
|
1618
|
-
const routes = defaultDocRegistry3.list();
|
|
1619
|
-
return createMcpElysiaHandler({
|
|
1620
|
-
logger: appLogger,
|
|
1621
|
-
path: path2,
|
|
1622
|
-
serverName: "contractspec-docs-mcp",
|
|
1623
|
-
ops: buildDocOps(routes),
|
|
1624
|
-
resources: buildDocResources(routes),
|
|
1625
|
-
prompts: buildDocPrompts(routes),
|
|
1626
|
-
presentations: options.includePresentations ? routes.map(({ descriptor }) => descriptor) : undefined
|
|
1627
|
-
});
|
|
1628
|
-
}
|
|
1629
|
-
|
|
1630
|
-
// src/application/mcp/internalMcp.ts
|
|
1631
|
-
import {
|
|
1632
|
-
defineCommand as defineCommand4,
|
|
1633
|
-
definePrompt as definePrompt4,
|
|
1634
|
-
defineResourceTemplate as defineResourceTemplate4,
|
|
1635
|
-
installOp as installOp4,
|
|
1636
|
-
OperationSpecRegistry as OperationSpecRegistry5,
|
|
1637
|
-
PromptRegistry as PromptRegistry4,
|
|
1638
|
-
ResourceRegistry as ResourceRegistry4
|
|
1639
|
-
} from "@contractspec/lib.contracts-spec";
|
|
1640
|
-
import { defineSchemaModel as defineSchemaModel4, ScalarTypeEnum as ScalarTypeEnum4 } from "@contractspec/lib.schema";
|
|
1641
|
-
import {
|
|
1642
|
-
getExample,
|
|
1643
|
-
listExamples,
|
|
1644
|
-
searchExamples
|
|
1645
|
-
} from "@contractspec/module.examples";
|
|
1646
|
-
import z5 from "zod";
|
|
1647
|
-
var INTERNAL_TAGS = ["internal", "mcp"];
|
|
1648
|
-
var INTERNAL_OWNERS = ["@contractspec"];
|
|
1649
|
-
var ENDPOINTS = {
|
|
1650
|
-
docs: "/api/mcp/docs",
|
|
1651
|
-
cli: "/api/mcp/cli",
|
|
1652
|
-
internal: "/api/mcp/internal",
|
|
1653
|
-
graphql: "/graphql",
|
|
1654
|
-
health: "/health"
|
|
1655
|
-
};
|
|
1656
|
-
function buildInternalResources() {
|
|
1657
|
-
const resources = new ResourceRegistry4;
|
|
1658
|
-
resources.register(defineResourceTemplate4({
|
|
1659
|
-
meta: {
|
|
1660
|
-
uriTemplate: "examples://list{?q}",
|
|
1661
|
-
title: "ContractSpec examples registry",
|
|
1662
|
-
description: "List available examples (templates, integrations, knowledge, scripts). Optional query `q` filters results.",
|
|
1663
|
-
mimeType: "application/json",
|
|
1664
|
-
tags: ["examples", ...INTERNAL_TAGS]
|
|
1665
|
-
},
|
|
1666
|
-
input: z5.object({ q: z5.string().optional() }),
|
|
1667
|
-
resolve: async ({ q }) => {
|
|
1668
|
-
const items = q ? searchExamples(q) : [...listExamples()];
|
|
1669
|
-
return {
|
|
1670
|
-
uri: q ? `examples://list?q=${encodeURIComponent(q)}` : "examples://list",
|
|
1671
|
-
mimeType: "application/json",
|
|
1672
|
-
data: JSON.stringify(items, null, 2)
|
|
1673
|
-
};
|
|
1674
|
-
}
|
|
1675
|
-
}));
|
|
1676
|
-
resources.register(defineResourceTemplate4({
|
|
1677
|
-
meta: {
|
|
1678
|
-
uriTemplate: "examples://example/{id}",
|
|
1679
|
-
title: "ContractSpec example (by id)",
|
|
1680
|
-
description: "Fetch a single example manifest by id.",
|
|
1681
|
-
mimeType: "application/json",
|
|
1682
|
-
tags: ["examples", ...INTERNAL_TAGS]
|
|
1683
|
-
},
|
|
1684
|
-
input: z5.object({ id: z5.string().min(1) }),
|
|
1685
|
-
resolve: async ({ id }) => {
|
|
1686
|
-
const example = getExample(id);
|
|
1687
|
-
if (!example) {
|
|
1688
|
-
return {
|
|
1689
|
-
uri: `examples://example/${encodeURIComponent(id)}`,
|
|
1690
|
-
mimeType: "application/json",
|
|
1691
|
-
data: JSON.stringify({ error: "not_found", id, message: `Unknown example id: ${id}` }, null, 2)
|
|
1692
|
-
};
|
|
1693
|
-
}
|
|
1694
|
-
return {
|
|
1695
|
-
uri: `examples://example/${encodeURIComponent(id)}`,
|
|
1696
|
-
mimeType: "application/json",
|
|
1697
|
-
data: JSON.stringify(example, null, 2)
|
|
1698
|
-
};
|
|
1699
|
-
}
|
|
1700
|
-
}));
|
|
1701
|
-
resources.register(defineResourceTemplate4({
|
|
1702
|
-
meta: {
|
|
1703
|
-
uriTemplate: "internal://endpoints",
|
|
1704
|
-
title: "ContractSpec MCP endpoints",
|
|
1705
|
-
description: "Endpoints for docs, CLI, internal MCP servers.",
|
|
1706
|
-
mimeType: "application/json",
|
|
1707
|
-
tags: INTERNAL_TAGS
|
|
1708
|
-
},
|
|
1709
|
-
input: z5.object({}),
|
|
1710
|
-
resolve: async () => ({
|
|
1711
|
-
uri: "internal://endpoints",
|
|
1712
|
-
mimeType: "application/json",
|
|
1713
|
-
data: JSON.stringify(ENDPOINTS, null, 2)
|
|
1714
|
-
})
|
|
1715
|
-
}));
|
|
1716
|
-
resources.register(defineResourceTemplate4({
|
|
1717
|
-
meta: {
|
|
1718
|
-
uriTemplate: "internal://playbook",
|
|
1719
|
-
title: "Internal MCP usage playbook",
|
|
1720
|
-
description: "How internal agents should discover docs, CLI usage, and endpoints.",
|
|
1721
|
-
mimeType: "text/markdown",
|
|
1722
|
-
tags: INTERNAL_TAGS
|
|
1723
|
-
},
|
|
1724
|
-
input: z5.object({}),
|
|
1725
|
-
resolve: async () => ({
|
|
1726
|
-
uri: "internal://playbook",
|
|
1727
|
-
mimeType: "text/markdown",
|
|
1728
|
-
data: [
|
|
1729
|
-
"# Internal MCP playbook",
|
|
1730
|
-
"- Connect to docs MCP first for canonical specs.",
|
|
1731
|
-
"- Use CLI MCP to surface quickstart/reference before running commands.",
|
|
1732
|
-
"- Keep calls read-only unless explicitly approved.",
|
|
1733
|
-
`- Endpoints: ${ENDPOINTS.docs}, ${ENDPOINTS.cli}, ${ENDPOINTS.internal}.`,
|
|
1734
|
-
"- For API work, GraphQL at /graphql; health at /health."
|
|
1735
|
-
].join(`
|
|
1736
|
-
`)
|
|
1737
|
-
})
|
|
1738
|
-
}));
|
|
1739
|
-
return resources;
|
|
1740
|
-
}
|
|
1741
|
-
function buildInternalPrompts() {
|
|
1742
|
-
const prompts = new PromptRegistry4;
|
|
1743
|
-
prompts.register(definePrompt4({
|
|
1744
|
-
meta: {
|
|
1745
|
-
key: "internal_bootstrap",
|
|
1746
|
-
version: "1.0.0",
|
|
1747
|
-
title: "Bootstrap internal ContractSpec agent",
|
|
1748
|
-
description: "Points agents to the correct MCP endpoints and guardrails.",
|
|
1749
|
-
tags: INTERNAL_TAGS,
|
|
1750
|
-
owners: INTERNAL_OWNERS,
|
|
1751
|
-
stability: "beta"
|
|
1752
|
-
},
|
|
1753
|
-
args: [],
|
|
1754
|
-
input: z5.object({}),
|
|
1755
|
-
render: async () => [
|
|
1756
|
-
{
|
|
1757
|
-
type: "text",
|
|
1758
|
-
text: "Start with internal://endpoints to pick the right MCP. Use docs MCP for specifications and CLI MCP for commands. Keep actions read-only unless explicitly approved."
|
|
1759
|
-
},
|
|
1760
|
-
{
|
|
1761
|
-
type: "resource",
|
|
1762
|
-
uri: "internal://endpoints",
|
|
1763
|
-
title: "Endpoints"
|
|
1764
|
-
}
|
|
1765
|
-
]
|
|
1766
|
-
}));
|
|
1767
|
-
return prompts;
|
|
1768
|
-
}
|
|
1769
|
-
function buildInternalOps() {
|
|
1770
|
-
const registry = new OperationSpecRegistry5;
|
|
1771
|
-
const InternalDescribeOutput = defineSchemaModel4({
|
|
1772
|
-
name: "InternalDescribeOutput",
|
|
1773
|
-
fields: {
|
|
1774
|
-
endpoints: {
|
|
1775
|
-
type: ScalarTypeEnum4.JSONObject(),
|
|
1776
|
-
isOptional: false
|
|
1777
|
-
},
|
|
1778
|
-
notes: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false }
|
|
1779
|
-
}
|
|
1780
|
-
});
|
|
1781
|
-
const describeSpec = defineCommand4({
|
|
1782
|
-
meta: {
|
|
1783
|
-
key: "internal_describe",
|
|
1784
|
-
version: "1.0.0",
|
|
1785
|
-
stability: "stable",
|
|
1786
|
-
owners: INTERNAL_OWNERS,
|
|
1787
|
-
tags: INTERNAL_TAGS,
|
|
1788
|
-
description: "Return MCP endpoints and guidance for internal ContractSpec agents.",
|
|
1789
|
-
goal: "Speed up internal development with the correct MCP entrypoints.",
|
|
1790
|
-
context: "Used by internal MCP surface; read-only."
|
|
1791
|
-
},
|
|
1792
|
-
io: {
|
|
1793
|
-
input: defineSchemaModel4({
|
|
1794
|
-
name: "InternalDescribeInput",
|
|
1795
|
-
fields: {}
|
|
1796
|
-
}),
|
|
1797
|
-
output: InternalDescribeOutput
|
|
1798
|
-
},
|
|
1799
|
-
policy: {
|
|
1800
|
-
auth: "anonymous"
|
|
1801
|
-
}
|
|
1802
|
-
});
|
|
1803
|
-
installOp4(registry, describeSpec, async () => ({
|
|
1804
|
-
endpoints: ENDPOINTS,
|
|
1805
|
-
notes: "Use docs MCP for canonical specs, CLI MCP for contractspec commands, and keep side-effecting actions gated behind human review."
|
|
1806
|
-
}));
|
|
1807
|
-
return registry;
|
|
1808
|
-
}
|
|
1809
|
-
function createInternalMcpHandler(path2 = "/api/mcp/internal") {
|
|
1810
|
-
return createMcpElysiaHandler({
|
|
1811
|
-
logger: appLogger,
|
|
1812
|
-
path: path2,
|
|
1813
|
-
serverName: "contractspec-internal-mcp",
|
|
1814
|
-
ops: buildInternalOps(),
|
|
1815
|
-
resources: buildInternalResources(),
|
|
1816
|
-
prompts: buildInternalPrompts()
|
|
1817
|
-
});
|
|
1818
|
-
}
|
|
1819
|
-
|
|
1820
|
-
// src/application/mcp/providerRankingMcp.ts
|
|
1821
|
-
import { getModelInfo } from "@contractspec/lib.ai-providers/models";
|
|
1822
|
-
import {
|
|
1823
|
-
definePrompt as definePrompt5,
|
|
1824
|
-
defineResourceTemplate as defineResourceTemplate5,
|
|
1825
|
-
installOp as installOp5,
|
|
1826
|
-
OperationSpecRegistry as OperationSpecRegistry6,
|
|
1827
|
-
PromptRegistry as PromptRegistry5,
|
|
1828
|
-
ResourceRegistry as ResourceRegistry5
|
|
1829
|
-
} from "@contractspec/lib.contracts-spec";
|
|
1830
|
-
import {
|
|
1831
|
-
BenchmarkIngestCommand,
|
|
1832
|
-
BenchmarkRunCustomCommand,
|
|
1833
|
-
RankingRefreshCommand
|
|
1834
|
-
} from "@contractspec/lib.contracts-spec/provider-ranking";
|
|
1835
|
-
import { InMemoryProviderRankingStore } from "@contractspec/lib.provider-ranking/in-memory-store";
|
|
1836
|
-
import { createDefaultIngesterRegistry } from "@contractspec/lib.provider-ranking/ingesters";
|
|
1837
|
-
import {
|
|
1838
|
-
computeModelRankings,
|
|
1839
|
-
normalizeBenchmarkResults
|
|
1840
|
-
} from "@contractspec/lib.provider-ranking/scoring";
|
|
1841
|
-
import z6 from "zod";
|
|
1842
|
-
var TransportFilterSchema = z6.enum(["rest", "mcp", "webhook", "sdk"]).optional();
|
|
1843
|
-
var AuthFilterSchema = z6.enum([
|
|
1844
|
-
"api-key",
|
|
1845
|
-
"oauth2",
|
|
1846
|
-
"bearer",
|
|
1847
|
-
"header",
|
|
1848
|
-
"basic",
|
|
1849
|
-
"webhook-signing",
|
|
1850
|
-
"service-account"
|
|
1851
|
-
]).optional();
|
|
1852
|
-
var RANKING_TAGS = ["ranking", "mcp", "ai"];
|
|
1853
|
-
var RANKING_OWNERS = ["platform.ai"];
|
|
1854
|
-
var sharedStore = null;
|
|
1855
|
-
function getStore() {
|
|
1856
|
-
if (!sharedStore) {
|
|
1857
|
-
sharedStore = new InMemoryProviderRankingStore;
|
|
1858
|
-
}
|
|
1859
|
-
return sharedStore;
|
|
1860
|
-
}
|
|
1861
|
-
function buildRankingResources() {
|
|
1862
|
-
const resources = new ResourceRegistry5;
|
|
1863
|
-
resources.register(defineResourceTemplate5({
|
|
1864
|
-
meta: {
|
|
1865
|
-
uriTemplate: "ranking://leaderboard",
|
|
1866
|
-
title: "AI Model Leaderboard",
|
|
1867
|
-
description: "Current ranked list of AI models by composite score. Supports optional transport and authMethod query filters.",
|
|
1868
|
-
mimeType: "application/json",
|
|
1869
|
-
tags: RANKING_TAGS
|
|
1870
|
-
},
|
|
1871
|
-
input: z6.object({
|
|
1872
|
-
transport: TransportFilterSchema,
|
|
1873
|
-
authMethod: AuthFilterSchema
|
|
1874
|
-
}),
|
|
1875
|
-
resolve: async ({ transport, authMethod }) => {
|
|
1876
|
-
const store = getStore();
|
|
1877
|
-
const result = await store.listModelRankings({
|
|
1878
|
-
limit: 100,
|
|
1879
|
-
requiredTransport: transport,
|
|
1880
|
-
requiredAuthMethod: authMethod
|
|
1881
|
-
});
|
|
1882
|
-
return {
|
|
1883
|
-
uri: "ranking://leaderboard",
|
|
1884
|
-
mimeType: "application/json",
|
|
1885
|
-
data: JSON.stringify(result, null, 2)
|
|
1886
|
-
};
|
|
1887
|
-
}
|
|
1888
|
-
}));
|
|
1889
|
-
resources.register(defineResourceTemplate5({
|
|
1890
|
-
meta: {
|
|
1891
|
-
uriTemplate: "ranking://leaderboard/{dimension}",
|
|
1892
|
-
title: "AI Model Leaderboard by Dimension",
|
|
1893
|
-
description: "Ranked list of AI models filtered by a specific dimension. Supports optional transport and authMethod query filters.",
|
|
1894
|
-
mimeType: "application/json",
|
|
1895
|
-
tags: RANKING_TAGS
|
|
1896
|
-
},
|
|
1897
|
-
input: z6.object({
|
|
1898
|
-
dimension: z6.string(),
|
|
1899
|
-
transport: TransportFilterSchema,
|
|
1900
|
-
authMethod: AuthFilterSchema
|
|
1901
|
-
}),
|
|
1902
|
-
resolve: async ({ dimension, transport, authMethod }) => {
|
|
1903
|
-
const store = getStore();
|
|
1904
|
-
const result = await store.listModelRankings({
|
|
1905
|
-
dimension,
|
|
1906
|
-
limit: 100,
|
|
1907
|
-
requiredTransport: transport,
|
|
1908
|
-
requiredAuthMethod: authMethod
|
|
1909
|
-
});
|
|
1910
|
-
return {
|
|
1911
|
-
uri: `ranking://leaderboard/${encodeURIComponent(dimension)}`,
|
|
1912
|
-
mimeType: "application/json",
|
|
1913
|
-
data: JSON.stringify(result, null, 2)
|
|
1914
|
-
};
|
|
1915
|
-
}
|
|
1916
|
-
}));
|
|
1917
|
-
resources.register(defineResourceTemplate5({
|
|
1918
|
-
meta: {
|
|
1919
|
-
uriTemplate: "ranking://model/{modelId}",
|
|
1920
|
-
title: "AI Model Profile",
|
|
1921
|
-
description: "Detailed profile for a specific AI model including scores and benchmarks.",
|
|
1922
|
-
mimeType: "application/json",
|
|
1923
|
-
tags: RANKING_TAGS
|
|
1924
|
-
},
|
|
1925
|
-
input: z6.object({ modelId: z6.string() }),
|
|
1926
|
-
resolve: async ({ modelId }) => {
|
|
1927
|
-
const store = getStore();
|
|
1928
|
-
const profile = await store.getModelProfile(modelId);
|
|
1929
|
-
if (!profile) {
|
|
1930
|
-
return {
|
|
1931
|
-
uri: `ranking://model/${encodeURIComponent(modelId)}`,
|
|
1932
|
-
mimeType: "application/json",
|
|
1933
|
-
data: JSON.stringify({ error: "not_found", modelId })
|
|
1934
|
-
};
|
|
1935
|
-
}
|
|
1936
|
-
const enriched = profile.costPerMillion == null ? (() => {
|
|
1937
|
-
const info = getModelInfo(profile.modelId);
|
|
1938
|
-
return info?.costPerMillion ? {
|
|
1939
|
-
...profile,
|
|
1940
|
-
costPerMillion: info.costPerMillion,
|
|
1941
|
-
displayName: info.name,
|
|
1942
|
-
contextWindow: info.contextWindow,
|
|
1943
|
-
capabilities: [
|
|
1944
|
-
...info.capabilities.vision ? ["vision"] : [],
|
|
1945
|
-
...info.capabilities.tools ? ["tools"] : [],
|
|
1946
|
-
...info.capabilities.reasoning ? ["reasoning"] : [],
|
|
1947
|
-
...info.capabilities.streaming ? ["streaming"] : []
|
|
1948
|
-
]
|
|
1949
|
-
} : profile;
|
|
1950
|
-
})() : profile;
|
|
1951
|
-
return {
|
|
1952
|
-
uri: `ranking://model/${encodeURIComponent(modelId)}`,
|
|
1953
|
-
mimeType: "application/json",
|
|
1954
|
-
data: JSON.stringify(enriched, null, 2)
|
|
1955
|
-
};
|
|
1956
|
-
}
|
|
1957
|
-
}));
|
|
1958
|
-
resources.register(defineResourceTemplate5({
|
|
1959
|
-
meta: {
|
|
1960
|
-
uriTemplate: "ranking://results",
|
|
1961
|
-
title: "Benchmark Results",
|
|
1962
|
-
description: "List of raw benchmark results from all ingested sources.",
|
|
1963
|
-
mimeType: "application/json",
|
|
1964
|
-
tags: RANKING_TAGS
|
|
1965
|
-
},
|
|
1966
|
-
input: z6.object({}),
|
|
1967
|
-
resolve: async () => {
|
|
1968
|
-
const store = getStore();
|
|
1969
|
-
const result = await store.listBenchmarkResults({ limit: 200 });
|
|
1970
|
-
return {
|
|
1971
|
-
uri: "ranking://results",
|
|
1972
|
-
mimeType: "application/json",
|
|
1973
|
-
data: JSON.stringify(result, null, 2)
|
|
1974
|
-
};
|
|
1975
|
-
}
|
|
1976
|
-
}));
|
|
1977
|
-
return resources;
|
|
1978
|
-
}
|
|
1979
|
-
function buildRankingPrompts() {
|
|
1980
|
-
const prompts = new PromptRegistry5;
|
|
1981
|
-
prompts.register(definePrompt5({
|
|
1982
|
-
meta: {
|
|
1983
|
-
key: "ranking.advisor",
|
|
1984
|
-
version: "1.0.0",
|
|
1985
|
-
title: "AI Model Advisor",
|
|
1986
|
-
description: "Which AI model is best for a given task? Uses the leaderboard to recommend.",
|
|
1987
|
-
tags: RANKING_TAGS,
|
|
1988
|
-
stability: "beta",
|
|
1989
|
-
owners: RANKING_OWNERS
|
|
1990
|
-
},
|
|
1991
|
-
args: [
|
|
1992
|
-
{
|
|
1993
|
-
name: "task",
|
|
1994
|
-
description: "The task or use case to recommend a model for.",
|
|
1995
|
-
required: true,
|
|
1996
|
-
schema: z6.string()
|
|
1997
|
-
},
|
|
1998
|
-
{
|
|
1999
|
-
name: "priority",
|
|
2000
|
-
description: "Priority dimension (coding, reasoning, cost, latency, etc.).",
|
|
2001
|
-
required: false,
|
|
2002
|
-
schema: z6.string().optional()
|
|
2003
|
-
},
|
|
2004
|
-
{
|
|
2005
|
-
name: "transport",
|
|
2006
|
-
description: "Required transport type (rest, mcp, webhook, sdk).",
|
|
2007
|
-
required: false,
|
|
2008
|
-
schema: TransportFilterSchema
|
|
2009
|
-
},
|
|
2010
|
-
{
|
|
2011
|
-
name: "authMethod",
|
|
2012
|
-
description: "Required auth method (api-key, oauth2, bearer, etc.).",
|
|
2013
|
-
required: false,
|
|
2014
|
-
schema: AuthFilterSchema
|
|
2015
|
-
}
|
|
2016
|
-
],
|
|
2017
|
-
input: z6.object({
|
|
2018
|
-
task: z6.string(),
|
|
2019
|
-
priority: z6.string().optional(),
|
|
2020
|
-
transport: TransportFilterSchema,
|
|
2021
|
-
authMethod: AuthFilterSchema
|
|
2022
|
-
}),
|
|
2023
|
-
render: async ({ task, priority, transport, authMethod }) => {
|
|
2024
|
-
const constraints = [];
|
|
2025
|
-
if (priority)
|
|
2026
|
-
constraints.push(`Prioritize: ${priority}.`);
|
|
2027
|
-
if (transport)
|
|
2028
|
-
constraints.push(`Required transport: ${transport}.`);
|
|
2029
|
-
if (authMethod)
|
|
2030
|
-
constraints.push(`Required auth: ${authMethod}.`);
|
|
2031
|
-
return [
|
|
2032
|
-
{
|
|
2033
|
-
type: "text",
|
|
2034
|
-
text: `Recommend the best AI model for: "${task}".${constraints.length ? ` ${constraints.join(" ")}` : ""} Use the leaderboard data to justify your recommendation.`
|
|
2035
|
-
},
|
|
2036
|
-
{
|
|
2037
|
-
type: "resource",
|
|
2038
|
-
uri: priority ? `ranking://leaderboard/${priority}` : "ranking://leaderboard",
|
|
2039
|
-
title: "Leaderboard"
|
|
2040
|
-
}
|
|
2041
|
-
];
|
|
2042
|
-
}
|
|
2043
|
-
}));
|
|
2044
|
-
return prompts;
|
|
2045
|
-
}
|
|
2046
|
-
function buildRankingOps() {
|
|
2047
|
-
const registry = new OperationSpecRegistry6;
|
|
2048
|
-
const ingesterRegistry = createDefaultIngesterRegistry();
|
|
2049
|
-
installOp5(registry, BenchmarkIngestCommand, async (args) => {
|
|
2050
|
-
const store = getStore();
|
|
2051
|
-
const source = args.source;
|
|
2052
|
-
const ingester = ingesterRegistry.get(source);
|
|
2053
|
-
if (!ingester) {
|
|
2054
|
-
throw new Error(`No ingester registered for source: ${source}`);
|
|
2055
|
-
}
|
|
2056
|
-
const rawResults = await ingester.ingest({
|
|
2057
|
-
sourceUrl: args.sourceUrl,
|
|
2058
|
-
dimensions: args.dimensions
|
|
2059
|
-
});
|
|
2060
|
-
const normalized = normalizeBenchmarkResults(rawResults);
|
|
2061
|
-
for (const result of normalized) {
|
|
2062
|
-
await store.upsertBenchmarkResult(result);
|
|
2063
|
-
}
|
|
2064
|
-
return {
|
|
2065
|
-
ingestionId: `ingest-${source}-${Date.now()}`,
|
|
2066
|
-
source,
|
|
2067
|
-
resultsCount: normalized.length,
|
|
2068
|
-
status: "completed",
|
|
2069
|
-
ingestedAt: new Date
|
|
2070
|
-
};
|
|
2071
|
-
});
|
|
2072
|
-
installOp5(registry, BenchmarkRunCustomCommand, async (args) => {
|
|
2073
|
-
return {
|
|
2074
|
-
runId: `custom-${Date.now()}`,
|
|
2075
|
-
evalSuiteKey: args.evalSuiteKey,
|
|
2076
|
-
modelId: args.modelId,
|
|
2077
|
-
status: "started",
|
|
2078
|
-
startedAt: new Date
|
|
2079
|
-
};
|
|
2080
|
-
});
|
|
2081
|
-
installOp5(registry, RankingRefreshCommand, async (args) => {
|
|
2082
|
-
const store = getStore();
|
|
2083
|
-
const allResults = [];
|
|
2084
|
-
let offset = 0;
|
|
2085
|
-
const pageSize = 500;
|
|
2086
|
-
while (true) {
|
|
2087
|
-
const page = await store.listBenchmarkResults({
|
|
2088
|
-
limit: pageSize,
|
|
2089
|
-
offset
|
|
2090
|
-
});
|
|
2091
|
-
allResults.push(...page.results);
|
|
2092
|
-
if (allResults.length >= page.total || page.results.length < pageSize)
|
|
2093
|
-
break;
|
|
2094
|
-
offset += pageSize;
|
|
2095
|
-
}
|
|
2096
|
-
const existingRankings = new Map((await store.listModelRankings({ limit: 1e4 })).rankings.map((r) => [
|
|
2097
|
-
r.modelId,
|
|
2098
|
-
r
|
|
2099
|
-
]));
|
|
2100
|
-
const weightOverrides = args.weightOverrides ? Array.isArray(args.weightOverrides) ? args.weightOverrides : [args.weightOverrides] : undefined;
|
|
2101
|
-
const newRankings = computeModelRankings(allResults, weightOverrides ? {
|
|
2102
|
-
weightOverrides
|
|
2103
|
-
} : undefined, existingRankings);
|
|
2104
|
-
for (const ranking of newRankings) {
|
|
2105
|
-
await store.upsertModelRanking(ranking);
|
|
2106
|
-
}
|
|
2107
|
-
return {
|
|
2108
|
-
modelsRanked: newRankings.length,
|
|
2109
|
-
updatedAt: new Date,
|
|
2110
|
-
status: "completed"
|
|
2111
|
-
};
|
|
2112
|
-
});
|
|
2113
|
-
return registry;
|
|
2114
|
-
}
|
|
2115
|
-
function createProviderRankingMcpHandler(path2 = "/api/mcp/ranking") {
|
|
2116
|
-
return createMcpElysiaHandler({
|
|
2117
|
-
logger: appLogger,
|
|
2118
|
-
path: path2,
|
|
2119
|
-
serverName: "contractspec-ranking-mcp",
|
|
2120
|
-
ops: buildRankingOps(),
|
|
2121
|
-
resources: buildRankingResources(),
|
|
2122
|
-
prompts: buildRankingPrompts()
|
|
2123
|
-
});
|
|
2124
|
-
}
|
|
2125
|
-
function setProviderRankingStore(store) {
|
|
2126
|
-
sharedStore = store;
|
|
2127
|
-
}
|
|
2128
|
-
export {
|
|
2129
|
-
setProviderRankingStore,
|
|
2130
|
-
createProviderRankingMcpHandler,
|
|
2131
|
-
createInternalMcpHandler,
|
|
2132
|
-
createDocsMcpHandler,
|
|
2133
|
-
createContractsMcpHandler,
|
|
2134
|
-
createContextStorageService,
|
|
2135
|
-
createCliMcpHandler
|
|
2136
|
-
};
|
|
5
|
+
contractspec validate <spec>`,reference:`# ContractSpec CLI reference
|
|
6
|
+
|
|
7
|
+
Key commands: create, build, validate. See README for full options.`,readme:`# ContractSpec CLI
|
|
8
|
+
|
|
9
|
+
Stabilize AI-generated code across API, DB, UI, events. Use create/build/validate commands.`},r=["cli","mcp"],kj=["@contractspec"],_Y=(()=>{let j=new Set([process.cwd(),l.resolve(process.cwd(),".."),l.resolve(process.cwd(),"../.."),l.resolve(process.cwd(),"../../..")]);if(typeof __dirname==="string")j.add(l.resolve(__dirname,"../../../../.."));return[...j]})(),s=new Map;async function MY(j){if(s.has(j))return s.get(j);let Y=LY[j];for(let Q of _Y){let $=l.resolve(Q,Y);try{let Z=await BY.readFile($,"utf8");return s.set(j,Z),Z}catch{}}let J=GY[j];return s.set(j,J),J}function bY(){let j=new qY;return j.register(zj({meta:{uriTemplate:"cli://doc/{slug}",title:"CLI documentation",description:"Quickstart, reference, and README for the CLI.",mimeType:"text/markdown",tags:r},input:k.object({slug:k.enum(["quickstart","reference","readme"])}),resolve:async({slug:Y})=>{let J=await MY(Y);return{uri:`cli://doc/${Y}`,mimeType:"text/markdown",data:J}}})),j.register(zj({meta:{uriTemplate:"cli://commands",title:"CLI commands summary",description:"Key ContractSpec CLI commands and when to use them.",mimeType:"application/json",tags:r},input:k.object({}),resolve:async()=>{return{uri:"cli://commands",mimeType:"application/json",data:JSON.stringify([{command:"contractspec create",summary:"Interactive wizard to author specs (with optional AI).",doc:"cli://doc/quickstart"},{command:"contractspec build <specPath>",summary:"Generate implementation code from a ContractSpec (agents + templates).",doc:"cli://doc/reference"},{command:"contractspec validate <specPath>",summary:"Validate specs and optionally check implementations against them.",doc:"cli://doc/reference"}],null,2)}}})),j}function DY(){let j=new PY;return j.register(FY({meta:{key:"cli.usage",version:"1.0.0",title:"Use ContractSpec CLI safely",description:"Remind agents to read CLI docs and pick commands from the canonical list.",tags:r,stability:"beta",owners:kj},args:[{name:"goal",description:"Task the user wants to achieve.",required:!1,schema:k.string().optional()}],input:k.object({goal:k.string().optional()}),render:async({goal:Y})=>[{type:"text",text:`Use CLI commands only from cli://commands. Prefer quickstart for newcomers and reference for options.${Y?` Goal: ${Y}.`:""}`},{type:"resource",uri:"cli://commands",title:"Commands"},{type:"resource",uri:"cli://doc/quickstart",title:"Quickstart"}]})),j}function NY(){let j=new xY,Y=Oj({name:"CliSuggestInput",fields:{goal:{type:d.String_unsecure(),isOptional:!1},prefersAi:{type:d.Boolean(),isOptional:!0}}}),J=Oj({name:"CliSuggestOutput",fields:{command:{type:d.String_unsecure(),isOptional:!1},docUri:{type:d.String_unsecure(),isOptional:!1},reason:{type:d.String_unsecure(),isOptional:!1}}}),Q=wY({meta:{key:"cli_suggestCommand",version:"1.0.0",stability:"stable",owners:kj,tags:r,description:"Recommend a CLI command for the requested goal.",goal:"Help AI agents choose the correct CLI entrypoint quickly.",context:"Used inside the CLI MCP server."},io:{input:Y,output:J},policy:{auth:"anonymous"}});return WY(j,Q,async({goal:$,prefersAi:Z})=>{let X=$.toLowerCase();if(X.includes("create")||X.includes("new"))return{command:Z?"contractspec create --ai":"contractspec create",docUri:"cli://doc/quickstart",reason:"Creates a new ContractSpec interactively (optionally with AI)."};if(X.includes("build")||X.includes("generate"))return{command:"contractspec build <path-to-spec>",docUri:"cli://doc/reference",reason:"Builds implementation code from a spec using agents + templates."};if(X.includes("validate")||X.includes("check"))return{command:"contractspec validate <path-to-spec>",docUri:"cli://doc/reference",reason:"Validates a spec and optionally checks its implementation for drift."};return{command:"contractspec --help",docUri:"cli://doc/readme",reason:"Fallback when the goal is unclear; read README for options."}}),j}function SJ(j="/api/mcp/cli"){return b({logger:M,path:j,serverName:"contractspec-cli-mcp",ops:NY(),resources:bY(),prompts:DY()})}import{definePrompt as AY,defineResourceTemplate as Gj,PromptRegistry as CY,ResourceRegistry as IY}from"@contractspec/lib.contracts-spec";import A from"zod";var EY=["@contractspec"],e=["contracts","mcp"];function Rj(j){let Y=new IY;return Y.register(Gj({meta:{uriTemplate:"contracts://list",title:"Contract specs list",description:"JSON list of all contract specs in the workspace.",mimeType:"application/json",tags:e},input:A.object({}),resolve:async()=>{let J=await j.listSpecs();return{uri:"contracts://list",mimeType:"application/json",data:JSON.stringify(J,null,2)}}})),Y.register(Gj({meta:{uriTemplate:"contracts://spec/{path}",title:"Contract spec content",description:"Read a single contract spec file by path.",mimeType:"text/plain",tags:e},input:A.object({path:A.string()}),resolve:async({path:J})=>{let Q=await j.getSpec(J);if(!Q)return{uri:`contracts://spec/${encodeURIComponent(J)}`,mimeType:"text/plain",data:`Spec not found: ${J}`};return{uri:`contracts://spec/${encodeURIComponent(J)}`,mimeType:"text/plain",data:Q.content}}})),Y.register(Gj({meta:{uriTemplate:"contracts://registry/manifest",title:"Remote registry manifest",description:"Contract registry manifest from the remote server.",mimeType:"application/json",tags:e},input:A.object({}),resolve:async()=>{let J=await j.fetchRegistryManifest();return{uri:"contracts://registry/manifest",mimeType:"application/json",data:JSON.stringify(J,null,2)}}})),Y}function vj(){let j=new CY;return j.register(AY({meta:{key:"contracts.editor",version:"1.0.0",title:"Contract editing guide",description:"Guide AI agents through reading, editing, and validating contracts.",tags:e,stability:"beta",owners:EY},args:[{name:"goal",description:"What the agent wants to achieve with the contract.",required:!1,schema:A.string().optional()}],input:A.object({goal:A.string().optional()}),render:async({goal:Y})=>[{type:"text",text:["Contract editing workflow:","1. Use contracts.list to discover specs","2. Use contracts.get to read a spec","3. Edit content and call contracts.update","4. Run contracts.validate to verify changes","5. Run contracts.build to regenerate artifacts",Y?`Agent goal: ${Y}`:""].filter(Boolean).join(`
|
|
10
|
+
`)},{type:"resource",uri:"contracts://list",title:"Available contracts"}]})),j}import{defineCommand as R,installOp as v,OperationSpecRegistry as zY}from"@contractspec/lib.contracts-spec";import{defineSchemaModel as _,ScalarTypeEnum as B}from"@contractspec/lib.schema";var T=["@contractspec"],f=["contracts","mcp"];function Tj(j){let Y=new zY,J=_({name:"ContractsListInput",fields:{pattern:{type:B.String_unsecure(),isOptional:!0},type:{type:B.String_unsecure(),isOptional:!0}}}),Q=_({name:"ContractsListOutput",fields:{specs:{type:B.JSON(),isOptional:!1},total:{type:B.Int_unsecure(),isOptional:!1}}});v(Y,R({meta:{key:"contracts.list",version:"1.0.0",stability:"beta",owners:T,tags:f,description:"List contract specs in the workspace.",goal:"Discover available contracts by type, pattern, or owner.",context:"Contracts MCP server."},io:{input:J,output:Q},policy:{auth:"anonymous"}}),async({pattern:V,type:H})=>{let G=await j.listSpecs({pattern:V,type:H});return{specs:G,total:G.length}});let $=_({name:"ContractsGetInput",fields:{path:{type:B.String_unsecure(),isOptional:!1}}}),Z=_({name:"ContractsGetOutput",fields:{content:{type:B.String_unsecure(),isOptional:!1},info:{type:B.JSON(),isOptional:!1}}});v(Y,R({meta:{key:"contracts.get",version:"1.0.0",stability:"beta",owners:T,tags:f,description:"Read a single contract spec file.",goal:"Fetch spec content and parsed metadata.",context:"Contracts MCP server."},io:{input:$,output:Z},policy:{auth:"anonymous"}}),async({path:V})=>{let H=await j.getSpec(V);if(!H)throw Error(`Spec not found: ${V}`);return H});let X=_({name:"ContractsValidateInput",fields:{path:{type:B.String_unsecure(),isOptional:!1}}}),U=_({name:"ContractsValidateOutput",fields:{valid:{type:B.Boolean(),isOptional:!1},errors:{type:B.JSON(),isOptional:!1},warnings:{type:B.JSON(),isOptional:!1}}});v(Y,R({meta:{key:"contracts.validate",version:"1.0.0",stability:"beta",owners:T,tags:f,description:"Validate a contract spec structure.",goal:"Check spec for structural or policy issues.",context:"Contracts MCP server."},io:{input:X,output:U},policy:{auth:"anonymous"}}),async({path:V})=>j.validateSpec(V));let K=_({name:"ContractsBuildInput",fields:{path:{type:B.String_unsecure(),isOptional:!1},dryRun:{type:B.Boolean(),isOptional:!0}}}),P=_({name:"ContractsBuildOutput",fields:{results:{type:B.JSON(),isOptional:!1}}});return v(Y,R({meta:{key:"contracts.build",version:"1.0.0",stability:"beta",owners:T,tags:f,description:"Generate implementation code from a contract spec.",goal:"Produce handler, component, or test skeletons.",context:"Contracts MCP server."},io:{input:K,output:P},policy:{auth:"user"}}),async({path:V,dryRun:H})=>j.buildSpec(V,{dryRun:H})),OY(Y,j),Y}function OY(j,Y){let J=_({name:"ContractsUpdateInput",fields:{path:{type:B.String_unsecure(),isOptional:!1},content:{type:B.String_unsecure(),isOptional:!0},fields:{type:B.JSON(),isOptional:!0}}}),Q=_({name:"ContractsUpdateOutput",fields:{updated:{type:B.Boolean(),isOptional:!1},errors:{type:B.JSON(),isOptional:!1},warnings:{type:B.JSON(),isOptional:!1}}});v(j,R({meta:{key:"contracts.update",version:"1.0.0",stability:"beta",owners:T,tags:f,description:"Update an existing contract spec.",goal:"Modify spec content or individual fields with validation.",context:"Contracts MCP server."},io:{input:J,output:Q},policy:{auth:"user"}}),async({path:X,content:U,fields:K})=>Y.updateSpec(X,{content:U,fields:Array.isArray(K)?K:void 0}));let $=_({name:"ContractsDeleteInput",fields:{path:{type:B.String_unsecure(),isOptional:!1},clean:{type:B.Boolean(),isOptional:!0}}}),Z=_({name:"ContractsDeleteOutput",fields:{deleted:{type:B.Boolean(),isOptional:!1},cleanedFiles:{type:B.JSON(),isOptional:!1},errors:{type:B.JSON(),isOptional:!1}}});v(j,R({meta:{key:"contracts.delete",version:"1.0.0",stability:"beta",owners:T,tags:f,description:"Delete a contract spec and optionally its artifacts.",goal:"Remove a spec file and clean generated handlers/tests.",context:"Contracts MCP server."},io:{input:$,output:Z},policy:{auth:"user"}}),async({path:X,clean:U})=>Y.deleteSpec(X,{clean:U}))}function oJ(j="/api/mcp/contracts",Y){return b({logger:M,path:j,serverName:"contractspec-contracts-mcp",ops:Tj(Y),resources:Rj(Y),prompts:vj()})}import{defaultDocRegistry as kY}from"@contractspec/lib.contracts-spec/docs";var RY=20,vY=100;function q(j){return j?.trim().toLowerCase()??""}function fj(j){let Y=decodeURIComponent(j).trim();if(!Y)return"/";return Y.startsWith("/")?Y:`/${Y}`}function TY(j){return(Array.isArray(j)?j:j?[j]:[]).map((J)=>q(J)).filter(Boolean)}function fY(j){if(!j||Number.isNaN(j))return RY;return Math.min(Math.max(j,1),vY)}function hY(j){if(!j||Number.isNaN(j))return 0;return Math.max(j,0)}function _j({block:j,route:Y}){return{id:j.id,title:j.title,summary:j.summary??"",route:Y,visibility:j.visibility??"public",kind:j.kind??"reference",version:j.version??"1.0.0",tags:j.tags??[]}}function SY(j,Y){if(!Y)return 1;let J=Y.split(/\s+/).filter(Boolean),Q=q(j.block.title),$=q(j.block.id),Z=q(j.block.summary),X=q(j.block.body),U=q(j.route),K=(j.block.tags??[]).map((H)=>q(H)),P=[Q,$,Z,X,U,...K].join(" ");if(J.some((H)=>!P.includes(H)))return 0;let V=0;for(let H of J){if($.includes(H))V+=8;if(Q.includes(H))V+=7;if(K.some((G)=>G.includes(H)))V+=5;if(Z.includes(H))V+=4;if(U.includes(H))V+=3;if(X.includes(H))V+=2}return V}function h(j,Y){let J=q(typeof Y.query==="string"?Y.query:void 0),Q=TY(Y.tag),$=q(typeof Y.visibility==="string"?Y.visibility:void 0),Z=q(typeof Y.kind==="string"?Y.kind:void 0),X=fY(typeof Y.limit==="number"?Y.limit:void 0),U=hY(typeof Y.offset==="number"?Y.offset:void 0),K=j.map((H)=>({doc:_j(H),score:SY(H,J)})).filter(({doc:H,score:G})=>{let Fj=J?G>0:!0,F=Q.length?Q.every((u)=>H.tags.some((N)=>q(N).includes(u))):!0,W=$?q(H.visibility)===$:!0,D=Z?q(H.kind)===Z:!0;return Fj&&F&&W&&D}).sort((H,G)=>{if(G.score!==H.score)return G.score-H.score;return H.doc.title.localeCompare(G.doc.title)}),P=K.slice(U,U+X).map(({doc:H})=>H),V=U+P.length<K.length?U+P.length:void 0;return{docs:P,items:P,total:K.length,...V!=null?{nextOffset:V}:{}}}function jj(j){let Y=decodeURIComponent(j),J=kY.get(Y);if(!J)return;return{doc:_j(J),content:String(J.block.body??"")}}function Yj(j,Y){let J=fj(Y),Q=j.find(($)=>fj($.route)===J);if(!Q)return;return{doc:_j(Q),content:String(Q.block.body??"")}}function Jj(j){let Y=new Map,J=new Map,Q=new Map;for(let Z of j){let X=Z.block.kind??"reference",U=Z.block.visibility??"public";J.set(X,(J.get(X)??0)+1),Q.set(U,(Q.get(U)??0)+1);for(let K of Z.block.tags??[])Y.set(K,(Y.get(K)??0)+1)}let $=(Z,X)=>[...Z.entries()].sort((U,K)=>K[1]-U[1]||U[0].localeCompare(K[0])).map(([U,K])=>({[X]:U,count:K}));return{totalDocs:j.length,tags:$(Y,"tag"),kinds:$(J,"kind"),visibilities:$(Q,"visibility")}}import{EventRegistry as yY,OperationSpecRegistry as mY}from"@contractspec/lib.contracts-spec";import{DataViewRegistry as gY}from"@contractspec/lib.contracts-spec/data-views";import{ContractReferenceDataView as uY,ContractReferenceQuery as dY,DocsGenerateCommand as lY,DocsGeneratedEvent as pY,DocsIndexDataView as nY,DocsIndexQuery as cY,DocsLayoutPresentation as iY,DocsPublishCommand as aY,DocsPublishedEvent as oY,DocsReferencePagePresentation as tY,DocsSearchForm as sY,ExampleCatalogDataView as rY}from"@contractspec/lib.contracts-spec/docs";import{FormRegistry as eY}from"@contractspec/lib.contracts-spec/forms";import{PresentationRegistry as j0}from"@contractspec/lib.contracts-spec/presentations";import{serializeDataViewSpec as Y0,serializeEventSpec as J0,serializeFormSpec as Q0,serializeOperationSpec as Z0,serializePresentationSpec as $0}from"@contractspec/lib.contracts-spec/serialization";var Qj=null;function X0(){let j=new mY;return j.register(cY).register(dY).register(lY).register(aY),j}function U0(){if(!Qj)Qj=X0();return Qj}function Mj(j,Y){return U0().get(j,Y)}var Zj=null;function V0(){let j=new yY;return j.register(pY).register(oY),j}function H0(){if(!Zj)Zj=V0();return Zj}function bj(j,Y){return H0().get(j,Y)}var $j=null;function K0(){let j=new j0;return j.register(iY).register(tY),j}function B0(){if(!$j)$j=K0();return $j}function Dj(j,Y){return B0().get(j,Y)}var Xj=null;function w0(){let j=new gY;return j.register(nY).register(uY).register(rY),j}function F0(){if(!Xj)Xj=w0();return Xj}function Nj(j,Y){return F0().get(j,Y)}var Uj=null;function W0(){let j=new eY;return j.register(sY),j}function x0(){if(!Uj)Uj=W0();return Uj}function Aj(j,Y){return x0().get(j)}function hj(j,Y){let J=Mj(j,Y);return Z0(J)??void 0}function Sj(j,Y){let J=bj(j,Y);return J0(J)??void 0}function yj(j,Y){let J=Dj(j,Y);return $0(J)??void 0}function mj(j,Y){let J=Nj(j,Y);return Y0(J)??void 0}function gj(j,Y){let J=Aj(j,Y);return Q0(J)??void 0}function P0(){Qj=null}function q0(){Zj=null}function L0(){$j=null}function G0(){Xj=null}function _0(){Uj=null}function $Q(){P0(),q0(),L0(),G0(),_0()}import{defaultDocRegistry as M0}from"@contractspec/lib.contracts-spec/docs";function b0(j){return j?.trim().toLowerCase()??""}function D0(j){for(let Y of j??[]){let J=M0.get(Y);if(J)return J.route}return}function uj(j,Y,J,Q){let $=j.meta.title??j.meta.key,Z=D0(j.meta.docId),X=j.meta.description;return{key:j.meta.key,version:j.meta.version,type:Y,title:$,description:X,markdown:[`# ${$}`,`- Key: ${j.meta.key}`,`- Type: ${Y}`,`- Version: ${j.meta.version}`,Z?`- Docs route: ${Z}`:"",X?`
|
|
11
|
+
${X}`:""].filter(Boolean).join(`
|
|
12
|
+
`),...Z?{route:Z}:{},...J?{schema:J}:{},...Q?{policy:Q}:{},tags:j.meta.tags??[],owners:j.meta.owners??[],stability:j.meta.stability}}function S(j){let Y=j.includeSchema??!1,J=b0(j.type),Q=Mj(j.key,j.version);if(Q&&(!J||J==="operation"||J===Q.meta.kind))return{reference:uj(Q,Q.meta.kind,Y?hj(j.key,j.version):void 0,Q.policy)};let $=[{type:"data-view",spec:Nj(j.key,j.version),schema:Y?mj(j.key,j.version):void 0},{type:"form",spec:Aj(j.key,j.version),schema:Y?gj(j.key,j.version):void 0},{type:"presentation",spec:Dj(j.key,j.version),schema:Y?yj(j.key,j.version):void 0},{type:"event",spec:bj(j.key,j.version),schema:Y?Sj(j.key,j.version):void 0}];for(let Z of $)if(Z.spec&&(!J||J===Z.type))return{reference:uj(Z.spec,Z.type,Z.schema)};throw Error(`Contract reference not found: ${j.key}`)}import{definePrompt as dj,PromptRegistry as N0}from"@contractspec/lib.contracts-spec";import x from"zod";var lj=["@contractspec"],pj=["docs","mcp"];function nj(j){let Y=new N0;return Y.register(dj({meta:{key:"docs.navigator",version:"1.0.0",title:"Find relevant ContractSpec docs",description:"Guide agents to search, filter, and open the right ContractSpec docs.",tags:pj,stability:"beta",owners:lj},args:[{name:"topic",description:"Goal or subject to search for.",required:!1,schema:x.string().optional()},{name:"kind",description:"Optional doc kind filter.",required:!1,schema:x.string().optional()},{name:"tag",description:"Optional tag filter.",required:!1,schema:x.string().optional()}],input:x.object({topic:x.string().optional(),kind:x.string().optional(),tag:x.string().optional()}),render:async({topic:J,kind:Q,tag:$})=>{let Z=h(j,{query:J,kind:Q,tag:$,limit:3}),X=Z.docs.length?Z.docs.map((U)=>`- ${U.title} (${U.id}) -> ${U.route}`).join(`
|
|
13
|
+
`):"- No direct pre-match. Use docs_list_facets-v1_0_0 to browse tags and kinds.";return[{type:"text",text:["Use docs_search-v1_0_0 first, then read docs://doc/{id} for the strongest matches.","Use docs_resolve_route-v1_0_0 when the user already gives you a docs URL or route.","Use docs_list_facets-v1_0_0 or docs://facets to browse the docs taxonomy before guessing.",J?`Topic: ${J}`:"",Q?`Kind: ${Q}`:"",$?`Tag: ${$}`:"","Suggested starting docs:",X].filter(Boolean).join(`
|
|
14
|
+
`)},{type:"resource",uri:"docs://index",title:"DocBlocks index"},{type:"resource",uri:"docs://facets",title:"Docs facets"}]}})),Y.register(dj({meta:{key:"docs.reference.guide",version:"1.0.0",title:"Resolve a ContractSpec reference",description:"Guide agents to fetch the canonical reference payload for a ContractSpec surface.",tags:pj,stability:"beta",owners:lj},args:[{name:"key",description:"ContractSpec key to resolve.",required:!0,schema:x.string()},{name:"version",description:"Optional version override.",required:!1,schema:x.string().optional()},{name:"type",description:"Optional surface type: command, query, form, data-view, presentation, event.",required:!1,schema:x.string().optional()}],input:x.object({key:x.string(),version:x.string().optional(),type:x.string().optional()}),render:async({key:J,version:Q,type:$})=>{let Z=S({key:J,version:Q,type:$,includeSchema:!0}).reference;return[{type:"text",text:["Use docs_contract_reference-v1_0_0 when you need the canonical docs payload for a ContractSpec surface.","Use docs_get-v1_0_0 only when you already know the exact DocBlock id and need raw markdown.",`Resolved key: ${Z.key}`,`Resolved type: ${Z.type}`,Z.route?`Docs route: ${Z.route}`:"",`Resource URI: docs://contract-reference/${encodeURIComponent(J)}`].filter(Boolean).join(`
|
|
15
|
+
`)},{type:"resource",uri:`docs://contract-reference/${encodeURIComponent(J)}`,title:"Contract reference"}]}})),Y}import{defineResourceTemplate as C,ResourceRegistry as A0}from"@contractspec/lib.contracts-spec";import w from"zod";var I=["docs","mcp"];function cj(j){let Y=new A0,J=(Q)=>h(j,Q);return Y.register(C({meta:{uriTemplate:"docs://index",title:"DocBlocks index",description:"Default ContractSpec docs index resource.",mimeType:"application/json",tags:I},input:w.object({}),resolve:async()=>({uri:"docs://index",mimeType:"application/json",data:JSON.stringify(J({}),null,2)})})),Y.register(C({meta:{uriTemplate:"docs://index{?query,tag,kind,visibility,limit,offset}",title:"DocBlocks index",description:"Search and paginate ContractSpec docs by query, tag, kind, or visibility.",mimeType:"application/json",tags:I},input:w.object({query:w.string().optional(),tag:w.string().optional(),kind:w.string().optional(),visibility:w.string().optional(),limit:w.coerce.number().optional(),offset:w.coerce.number().optional()}),resolve:async(Q)=>({uri:"docs://index",mimeType:"application/json",data:JSON.stringify(J(Q),null,2)})})),Y.register(C({meta:{uriTemplate:"docs://list",title:"DocBlocks index (legacy alias)",description:"Compatibility alias for the docs index resource.",mimeType:"application/json",tags:I},input:w.object({}),resolve:async()=>({uri:"docs://list",mimeType:"application/json",data:JSON.stringify(J({}),null,2)})})),Y.register(C({meta:{uriTemplate:"docs://doc/{id}",title:"Doc markdown",description:"Fetch a single DocBlock body by id as markdown.",mimeType:"text/markdown",tags:I},input:w.object({id:w.string()}),resolve:async({id:Q})=>{let $=jj(Q);if(!$)return{uri:`docs://doc/${encodeURIComponent(Q)}`,mimeType:"text/plain",data:`DocBlock not found: ${Q}`};return{uri:`docs://doc/${encodeURIComponent(Q)}`,mimeType:"text/markdown",data:$.content}}})),Y.register(C({meta:{uriTemplate:"docs://route/{routePath}",title:"Doc by route",description:"Resolve a docs route to the matching DocBlock summary and body.",mimeType:"application/json",tags:I},input:w.object({routePath:w.string()}),resolve:async({routePath:Q})=>({uri:`docs://route/${encodeURIComponent(Q)}`,mimeType:"application/json",data:JSON.stringify(Yj(j,Q)??{error:"not_found",route:Q},null,2)})})),Y.register(C({meta:{uriTemplate:"docs://facets",title:"Docs facets",description:"Counts of available tags, kinds, and visibilities across docs.",mimeType:"application/json",tags:I},input:w.object({}),resolve:async()=>({uri:"docs://facets",mimeType:"application/json",data:JSON.stringify(Jj(j),null,2)})})),Y.register(C({meta:{uriTemplate:"docs://contract-reference/{key}{?version,type,includeSchema}",title:"Contract reference",description:"Resolve a ContractSpec surface into a docs-ready reference payload.",mimeType:"application/json",tags:I},input:w.object({key:w.string(),version:w.string().optional(),type:w.string().optional(),includeSchema:w.coerce.boolean().optional()}),resolve:async({key:Q,version:$,type:Z,includeSchema:X})=>({uri:`docs://contract-reference/${encodeURIComponent(Q)}`,mimeType:"application/json",data:JSON.stringify(S({key:Q,version:$,type:Z,includeSchema:X}),null,2)})})),Y}import{defineCommand as p,defineSchemaModel as y,installOp as n,OperationSpecRegistry as C0}from"@contractspec/lib.contracts-spec";import{ContractReferenceInput as I0,ContractReferenceOutput as E0,DocsIndexInput as z0,DocsIndexOutput as O0}from"@contractspec/lib.contracts-spec/docs";import{ScalarTypeEnum as E}from"@contractspec/lib.schema";var c=["@contractspec"],i=["docs","mcp"],k0=y({name:"DocsGetInput",fields:{id:{type:E.String_unsecure(),isOptional:!1}}}),R0=y({name:"DocsGetOutput",fields:{doc:{type:E.JSON(),isOptional:!1},content:{type:E.String_unsecure(),isOptional:!1}}}),v0=y({name:"DocsResolveRouteInput",fields:{route:{type:E.String_unsecure(),isOptional:!1}}}),T0=y({name:"DocsResolveRouteOutput",fields:{doc:{type:E.JSON(),isOptional:!1},content:{type:E.String_unsecure(),isOptional:!1}}}),f0=y({name:"DocsFacetsInput",fields:{}}),h0=y({name:"DocsFacetsOutput",fields:{facets:{type:E.JSON(),isOptional:!1}}});function ij(j){let Y=new C0;return n(Y,p({meta:{key:"docs.search",version:"1.0.0",stability:"beta",owners:c,tags:i,description:"Search ContractSpec docs by query, tag, kind, or visibility.",goal:"Find the most relevant DocBlocks without browsing the full corpus.",context:"Read-only docs MCP search surface."},io:{input:z0,output:O0},policy:{auth:"anonymous"},transport:{mcp:{toolName:"docs_search-v1_0_0"}}}),async(J)=>h(j,J)),n(Y,p({meta:{key:"docs.get",version:"1.0.0",stability:"beta",owners:c,tags:i,description:"Read a single DocBlock by id.",goal:"Fetch the exact markdown content and metadata for a known doc id.",context:"Read-only docs MCP surface."},io:{input:k0,output:R0},policy:{auth:"anonymous"},transport:{mcp:{toolName:"docs_get-v1_0_0"}}}),async({id:J})=>{let Q=jj(J);if(!Q)throw Error(`DocBlock not found: ${J}`);return Q}),n(Y,p({meta:{key:"docs.resolveRoute",version:"1.0.0",stability:"beta",owners:c,tags:i,description:"Resolve a docs route to the matching DocBlock.",goal:"Turn a route or URL path into a canonical doc id and markdown body.",context:"Read-only docs MCP surface."},io:{input:v0,output:T0},policy:{auth:"anonymous"},transport:{mcp:{toolName:"docs_resolve_route-v1_0_0"}}}),async({route:J})=>{let Q=Yj(j,J);if(!Q)throw Error(`Doc route not found: ${J}`);return Q}),n(Y,p({meta:{key:"docs.contract.lookup",version:"1.0.0",stability:"beta",owners:c,tags:i,description:"Resolve a ContractSpec surface into a docs-ready reference payload.",goal:"Get canonical docs metadata, route, and optional schema for a spec key.",context:"Read-only docs MCP surface."},io:{input:I0,output:E0},policy:{auth:"anonymous"},transport:{mcp:{toolName:"docs_contract_reference-v1_0_0"}}}),async(J)=>S(J)),n(Y,p({meta:{key:"docs.list.facets",version:"1.0.0",stability:"beta",owners:c,tags:i,description:"List docs taxonomy facets such as tags, kinds, and visibilities.",goal:"Help agents browse the docs corpus before making targeted reads.",context:"Read-only docs MCP surface."},io:{input:f0,output:h0},policy:{auth:"anonymous"},transport:{mcp:{toolName:"docs_list_facets-v1_0_0"}}}),async()=>({facets:Jj(j)})),Y}import{defaultDocRegistry as S0}from"@contractspec/lib.contracts-spec/docs";function RQ(j="/api/mcp/docs",Y={}){let J=S0.list();return b({logger:M,path:j,serverName:"contractspec-docs-mcp",ops:ij(J),resources:cj(J),prompts:nj(J),presentations:Y.includePresentations?J.map(({descriptor:Q})=>Q):void 0})}import{defineCommand as y0,definePrompt as m0,defineResourceTemplate as Vj,installOp as g0,OperationSpecRegistry as u0,PromptRegistry as d0,ResourceRegistry as l0}from"@contractspec/lib.contracts-spec";import{defineSchemaModel as aj,ScalarTypeEnum as oj}from"@contractspec/lib.schema";import{getExample as p0,listExamples as n0,searchExamples as c0}from"@contractspec/module.examples";import z from"zod";var m=["internal","mcp"],tj=["@contractspec"],a={docs:"/api/mcp/docs",cli:"/api/mcp/cli",internal:"/api/mcp/internal",graphql:"/graphql",health:"/health"};function i0(){let j=new l0;return j.register(Vj({meta:{uriTemplate:"examples://list{?q}",title:"ContractSpec examples registry",description:"List available examples (templates, integrations, knowledge, scripts). Optional query `q` filters results.",mimeType:"application/json",tags:["examples",...m]},input:z.object({q:z.string().optional()}),resolve:async({q:Y})=>{let J=Y?c0(Y):[...n0()];return{uri:Y?`examples://list?q=${encodeURIComponent(Y)}`:"examples://list",mimeType:"application/json",data:JSON.stringify(J,null,2)}}})),j.register(Vj({meta:{uriTemplate:"examples://example/{id}",title:"ContractSpec example (by id)",description:"Fetch a single example manifest by id.",mimeType:"application/json",tags:["examples",...m]},input:z.object({id:z.string().min(1)}),resolve:async({id:Y})=>{let J=p0(Y);if(!J)return{uri:`examples://example/${encodeURIComponent(Y)}`,mimeType:"application/json",data:JSON.stringify({error:"not_found",id:Y,message:`Unknown example id: ${Y}`},null,2)};return{uri:`examples://example/${encodeURIComponent(Y)}`,mimeType:"application/json",data:JSON.stringify(J,null,2)}}})),j.register(Vj({meta:{uriTemplate:"internal://endpoints",title:"ContractSpec MCP endpoints",description:"Endpoints for docs, CLI, internal MCP servers.",mimeType:"application/json",tags:m},input:z.object({}),resolve:async()=>({uri:"internal://endpoints",mimeType:"application/json",data:JSON.stringify(a,null,2)})})),j.register(Vj({meta:{uriTemplate:"internal://playbook",title:"Internal MCP usage playbook",description:"How internal agents should discover docs, CLI usage, and endpoints.",mimeType:"text/markdown",tags:m},input:z.object({}),resolve:async()=>({uri:"internal://playbook",mimeType:"text/markdown",data:["# Internal MCP playbook","- Connect to docs MCP first for canonical specs.","- Use CLI MCP to surface quickstart/reference before running commands.","- Keep calls read-only unless explicitly approved.",`- Endpoints: ${a.docs}, ${a.cli}, ${a.internal}.`,"- For API work, GraphQL at /graphql; health at /health."].join(`
|
|
16
|
+
`)})})),j}function a0(){let j=new d0;return j.register(m0({meta:{key:"internal_bootstrap",version:"1.0.0",title:"Bootstrap internal ContractSpec agent",description:"Points agents to the correct MCP endpoints and guardrails.",tags:m,owners:tj,stability:"beta"},args:[],input:z.object({}),render:async()=>[{type:"text",text:"Start with internal://endpoints to pick the right MCP. Use docs MCP for specifications and CLI MCP for commands. Keep actions read-only unless explicitly approved."},{type:"resource",uri:"internal://endpoints",title:"Endpoints"}]})),j}function o0(){let j=new u0,Y=aj({name:"InternalDescribeOutput",fields:{endpoints:{type:oj.JSONObject(),isOptional:!1},notes:{type:oj.String_unsecure(),isOptional:!1}}}),J=y0({meta:{key:"internal_describe",version:"1.0.0",stability:"stable",owners:tj,tags:m,description:"Return MCP endpoints and guidance for internal ContractSpec agents.",goal:"Speed up internal development with the correct MCP entrypoints.",context:"Used by internal MCP surface; read-only."},io:{input:aj({name:"InternalDescribeInput",fields:{}}),output:Y},policy:{auth:"anonymous"}});return g0(j,J,async()=>({endpoints:a,notes:"Use docs MCP for canonical specs, CLI MCP for contractspec commands, and keep side-effecting actions gated behind human review."})),j}function gQ(j="/api/mcp/internal"){return b({logger:M,path:j,serverName:"contractspec-internal-mcp",ops:o0(),resources:i0(),prompts:a0()})}import{getModelInfo as t0}from"@contractspec/lib.ai-providers/models";import{definePrompt as s0,defineResourceTemplate as Hj,installOp as Cj,OperationSpecRegistry as r0,PromptRegistry as e0,ResourceRegistry as jJ}from"@contractspec/lib.contracts-spec";import{BenchmarkIngestCommand as YJ,BenchmarkRunCustomCommand as JJ,RankingRefreshCommand as QJ}from"@contractspec/lib.contracts-spec/provider-ranking";import{InMemoryProviderRankingStore as ZJ}from"@contractspec/lib.provider-ranking/in-memory-store";import{createDefaultIngesterRegistry as $J}from"@contractspec/lib.provider-ranking/ingesters";import{computeModelRankings as XJ,normalizeBenchmarkResults as UJ}from"@contractspec/lib.provider-ranking/scoring";import L from"zod";var Bj=L.enum(["rest","mcp","webhook","sdk"]).optional(),wj=L.enum(["api-key","oauth2","bearer","header","basic","webhook-signing","service-account"]).optional(),o=["ranking","mcp","ai"],VJ=["platform.ai"],Kj=null;function g(){if(!Kj)Kj=new ZJ;return Kj}function HJ(){let j=new jJ;return j.register(Hj({meta:{uriTemplate:"ranking://leaderboard",title:"AI Model Leaderboard",description:"Current ranked list of AI models by composite score. Supports optional transport and authMethod query filters.",mimeType:"application/json",tags:o},input:L.object({transport:Bj,authMethod:wj}),resolve:async({transport:Y,authMethod:J})=>{let $=await g().listModelRankings({limit:100,requiredTransport:Y,requiredAuthMethod:J});return{uri:"ranking://leaderboard",mimeType:"application/json",data:JSON.stringify($,null,2)}}})),j.register(Hj({meta:{uriTemplate:"ranking://leaderboard/{dimension}",title:"AI Model Leaderboard by Dimension",description:"Ranked list of AI models filtered by a specific dimension. Supports optional transport and authMethod query filters.",mimeType:"application/json",tags:o},input:L.object({dimension:L.string(),transport:Bj,authMethod:wj}),resolve:async({dimension:Y,transport:J,authMethod:Q})=>{let Z=await g().listModelRankings({dimension:Y,limit:100,requiredTransport:J,requiredAuthMethod:Q});return{uri:`ranking://leaderboard/${encodeURIComponent(Y)}`,mimeType:"application/json",data:JSON.stringify(Z,null,2)}}})),j.register(Hj({meta:{uriTemplate:"ranking://model/{modelId}",title:"AI Model Profile",description:"Detailed profile for a specific AI model including scores and benchmarks.",mimeType:"application/json",tags:o},input:L.object({modelId:L.string()}),resolve:async({modelId:Y})=>{let Q=await g().getModelProfile(Y);if(!Q)return{uri:`ranking://model/${encodeURIComponent(Y)}`,mimeType:"application/json",data:JSON.stringify({error:"not_found",modelId:Y})};let $=Q.costPerMillion==null?(()=>{let Z=t0(Q.modelId);return Z?.costPerMillion?{...Q,costPerMillion:Z.costPerMillion,displayName:Z.name,contextWindow:Z.contextWindow,capabilities:[...Z.capabilities.vision?["vision"]:[],...Z.capabilities.tools?["tools"]:[],...Z.capabilities.reasoning?["reasoning"]:[],...Z.capabilities.streaming?["streaming"]:[]]}:Q})():Q;return{uri:`ranking://model/${encodeURIComponent(Y)}`,mimeType:"application/json",data:JSON.stringify($,null,2)}}})),j.register(Hj({meta:{uriTemplate:"ranking://results",title:"Benchmark Results",description:"List of raw benchmark results from all ingested sources.",mimeType:"application/json",tags:o},input:L.object({}),resolve:async()=>{let J=await g().listBenchmarkResults({limit:200});return{uri:"ranking://results",mimeType:"application/json",data:JSON.stringify(J,null,2)}}})),j}function KJ(){let j=new e0;return j.register(s0({meta:{key:"ranking.advisor",version:"1.0.0",title:"AI Model Advisor",description:"Which AI model is best for a given task? Uses the leaderboard to recommend.",tags:o,stability:"beta",owners:VJ},args:[{name:"task",description:"The task or use case to recommend a model for.",required:!0,schema:L.string()},{name:"priority",description:"Priority dimension (coding, reasoning, cost, latency, etc.).",required:!1,schema:L.string().optional()},{name:"transport",description:"Required transport type (rest, mcp, webhook, sdk).",required:!1,schema:Bj},{name:"authMethod",description:"Required auth method (api-key, oauth2, bearer, etc.).",required:!1,schema:wj}],input:L.object({task:L.string(),priority:L.string().optional(),transport:Bj,authMethod:wj}),render:async({task:Y,priority:J,transport:Q,authMethod:$})=>{let Z=[];if(J)Z.push(`Prioritize: ${J}.`);if(Q)Z.push(`Required transport: ${Q}.`);if($)Z.push(`Required auth: ${$}.`);return[{type:"text",text:`Recommend the best AI model for: "${Y}".${Z.length?` ${Z.join(" ")}`:""} Use the leaderboard data to justify your recommendation.`},{type:"resource",uri:J?`ranking://leaderboard/${J}`:"ranking://leaderboard",title:"Leaderboard"}]}})),j}function BJ(){let j=new r0,Y=$J();return Cj(j,YJ,async(J)=>{let Q=g(),$=J.source,Z=Y.get($);if(!Z)throw Error(`No ingester registered for source: ${$}`);let X=await Z.ingest({sourceUrl:J.sourceUrl,dimensions:J.dimensions}),U=UJ(X);for(let K of U)await Q.upsertBenchmarkResult(K);return{ingestionId:`ingest-${$}-${Date.now()}`,source:$,resultsCount:U.length,status:"completed",ingestedAt:new Date}}),Cj(j,JJ,async(J)=>{return{runId:`custom-${Date.now()}`,evalSuiteKey:J.evalSuiteKey,modelId:J.modelId,status:"started",startedAt:new Date}}),Cj(j,QJ,async(J)=>{let Q=g(),$=[],Z=0,X=500;while(!0){let V=await Q.listBenchmarkResults({limit:X,offset:Z});if($.push(...V.results),$.length>=V.total||V.results.length<X)break;Z+=X}let U=new Map((await Q.listModelRankings({limit:1e4})).rankings.map((V)=>[V.modelId,V])),K=J.weightOverrides?Array.isArray(J.weightOverrides)?J.weightOverrides:[J.weightOverrides]:void 0,P=XJ($,K?{weightOverrides:K}:void 0,U);for(let V of P)await Q.upsertModelRanking(V);return{modelsRanked:P.length,updatedAt:new Date,status:"completed"}}),j}function sQ(j="/api/mcp/ranking"){return b({logger:M,path:j,serverName:"contractspec-ranking-mcp",ops:BJ(),resources:HJ(),prompts:KJ()})}function rQ(j){Kj=j}export{rQ as setProviderRankingStore,sQ as createProviderRankingMcpHandler,gQ as createInternalMcpHandler,RQ as createDocsMcpHandler,oJ as createContractsMcpHandler,xJ as createContextStorageService,SJ as createCliMcpHandler};
|