@ucptools/validator 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/CLAUDE.md +109 -0
  2. package/CONTRIBUTING.md +113 -0
  3. package/LICENSE +21 -0
  4. package/README.md +203 -0
  5. package/api/analyze-feed.js +140 -0
  6. package/api/badge.js +185 -0
  7. package/api/benchmark.js +177 -0
  8. package/api/directory-stats.ts +29 -0
  9. package/api/directory.ts +73 -0
  10. package/api/generate-compliance.js +143 -0
  11. package/api/generate-schema.js +457 -0
  12. package/api/generate.js +132 -0
  13. package/api/security-scan.js +133 -0
  14. package/api/simulate.js +187 -0
  15. package/api/tsconfig.json +10 -0
  16. package/api/validate.js +1351 -0
  17. package/apify-actor/.actor/actor.json +68 -0
  18. package/apify-actor/.actor/input_schema.json +32 -0
  19. package/apify-actor/APIFY-STORE-LISTING.md +412 -0
  20. package/apify-actor/Dockerfile +8 -0
  21. package/apify-actor/README.md +166 -0
  22. package/apify-actor/main.ts +111 -0
  23. package/apify-actor/package.json +17 -0
  24. package/apify-actor/src/main.js +199 -0
  25. package/docs/BRAND-IDENTITY.md +238 -0
  26. package/docs/BRAND-STYLE-GUIDE.md +356 -0
  27. package/drizzle/0000_black_king_cobra.sql +39 -0
  28. package/drizzle/meta/0000_snapshot.json +309 -0
  29. package/drizzle/meta/_journal.json +13 -0
  30. package/drizzle.config.ts +10 -0
  31. package/examples/full-profile.json +70 -0
  32. package/examples/minimal-profile.json +23 -0
  33. package/package.json +69 -0
  34. package/public/.well-known/ucp +25 -0
  35. package/public/android-chrome-192x192.png +0 -0
  36. package/public/android-chrome-512x512.png +0 -0
  37. package/public/apple-touch-icon.png +0 -0
  38. package/public/brand.css +321 -0
  39. package/public/directory.html +701 -0
  40. package/public/favicon-16x16.png +0 -0
  41. package/public/favicon-32x32.png +0 -0
  42. package/public/favicon.ico +0 -0
  43. package/public/guides/bigcommerce.html +743 -0
  44. package/public/guides/fastucp.html +838 -0
  45. package/public/guides/magento.html +779 -0
  46. package/public/guides/shopify.html +726 -0
  47. package/public/guides/squarespace.html +749 -0
  48. package/public/guides/wix.html +747 -0
  49. package/public/guides/woocommerce.html +733 -0
  50. package/public/index.html +3835 -0
  51. package/public/learn.html +396 -0
  52. package/public/logo.jpeg +0 -0
  53. package/public/og-image-icon.png +0 -0
  54. package/public/og-image.png +0 -0
  55. package/public/robots.txt +6 -0
  56. package/public/site.webmanifest +31 -0
  57. package/public/sitemap.xml +69 -0
  58. package/public/social/linkedin-banner-1128x191.png +0 -0
  59. package/public/social/temp.PNG +0 -0
  60. package/public/social/x-header-1500x500.png +0 -0
  61. package/public/verify.html +410 -0
  62. package/scripts/generate-favicons.js +44 -0
  63. package/scripts/generate-ico.js +23 -0
  64. package/scripts/generate-og-image.js +45 -0
  65. package/scripts/reset-db.ts +77 -0
  66. package/scripts/seed-db.ts +71 -0
  67. package/scripts/setup-benchmark-db.js +70 -0
  68. package/src/api/server.ts +266 -0
  69. package/src/cli/index.ts +302 -0
  70. package/src/compliance/compliance-generator.ts +452 -0
  71. package/src/compliance/index.ts +28 -0
  72. package/src/compliance/templates.ts +338 -0
  73. package/src/compliance/types.ts +170 -0
  74. package/src/db/index.ts +28 -0
  75. package/src/db/schema.ts +84 -0
  76. package/src/feed-analyzer/feed-analyzer.ts +726 -0
  77. package/src/feed-analyzer/index.ts +34 -0
  78. package/src/feed-analyzer/types.ts +354 -0
  79. package/src/generator/index.ts +7 -0
  80. package/src/generator/key-generator.ts +124 -0
  81. package/src/generator/profile-builder.ts +402 -0
  82. package/src/hosting/artifacts-generator.ts +679 -0
  83. package/src/hosting/index.ts +6 -0
  84. package/src/index.ts +105 -0
  85. package/src/security/index.ts +15 -0
  86. package/src/security/security-scanner.ts +604 -0
  87. package/src/security/types.ts +55 -0
  88. package/src/services/directory.ts +434 -0
  89. package/src/simulator/agent-simulator.ts +941 -0
  90. package/src/simulator/index.ts +7 -0
  91. package/src/simulator/types.ts +170 -0
  92. package/src/types/generator.ts +140 -0
  93. package/src/types/index.ts +7 -0
  94. package/src/types/ucp-profile.ts +140 -0
  95. package/src/types/validation.ts +89 -0
  96. package/src/validator/index.ts +194 -0
  97. package/src/validator/network-validator.ts +417 -0
  98. package/src/validator/rules-validator.ts +297 -0
  99. package/src/validator/sdk-validator.ts +330 -0
  100. package/src/validator/structural-validator.ts +476 -0
  101. package/tests/fixtures/non-compliant-profile.json +25 -0
  102. package/tests/fixtures/official-sample-profile.json +75 -0
  103. package/tests/integration/benchmark.test.ts +207 -0
  104. package/tests/integration/database.test.ts +163 -0
  105. package/tests/integration/directory-api.test.ts +268 -0
  106. package/tests/integration/simulate-api.test.ts +230 -0
  107. package/tests/integration/validate-api.test.ts +269 -0
  108. package/tests/setup.ts +15 -0
  109. package/tests/unit/agent-simulator.test.ts +575 -0
  110. package/tests/unit/compliance-generator.test.ts +374 -0
  111. package/tests/unit/directory-service.test.ts +272 -0
  112. package/tests/unit/feed-analyzer.test.ts +517 -0
  113. package/tests/unit/lint-suggestions.test.ts +423 -0
  114. package/tests/unit/official-samples.test.ts +211 -0
  115. package/tests/unit/pdf-report.test.ts +390 -0
  116. package/tests/unit/sdk-validator.test.ts +531 -0
  117. package/tests/unit/security-scanner.test.ts +410 -0
  118. package/tests/unit/validation.test.ts +390 -0
  119. package/tsconfig.json +20 -0
  120. package/vercel.json +34 -0
  121. package/vitest.config.ts +22 -0
@@ -0,0 +1,7 @@
1
+ /**
2
+ * AI Agent Simulator Module
3
+ * Exports for simulating AI agent interactions with UCP merchants
4
+ */
5
+
6
+ export * from './types.js';
7
+ export * from './agent-simulator.js';
@@ -0,0 +1,170 @@
1
+ /**
2
+ * AI Agent Simulation Types
3
+ * Types for simulating AI agent interactions with UCP merchants
4
+ */
5
+
6
+ /**
7
+ * Simulation step status
8
+ */
9
+ export type SimulationStepStatus = 'passed' | 'failed' | 'skipped' | 'warning';
10
+
11
+ /**
12
+ * Individual simulation step result
13
+ */
14
+ export interface SimulationStepResult {
15
+ step: string;
16
+ status: SimulationStepStatus;
17
+ message: string;
18
+ details?: string;
19
+ durationMs?: number;
20
+ data?: Record<string, unknown>;
21
+ }
22
+
23
+ /**
24
+ * Discovery flow simulation results
25
+ */
26
+ export interface DiscoveryFlowResult {
27
+ success: boolean;
28
+ steps: SimulationStepResult[];
29
+ profileUrl?: string;
30
+ capabilities: string[];
31
+ services: string[];
32
+ transports: string[];
33
+ }
34
+
35
+ /**
36
+ * Capability inspection result
37
+ */
38
+ export interface CapabilityInspectionResult {
39
+ name: string;
40
+ version: string;
41
+ schemaAccessible: boolean;
42
+ specAccessible: boolean;
43
+ isExtension: boolean;
44
+ parentCapability?: string;
45
+ }
46
+
47
+ /**
48
+ * Service inspection result
49
+ */
50
+ export interface ServiceInspectionResult {
51
+ name: string;
52
+ version: string;
53
+ transports: {
54
+ rest?: {
55
+ endpoint: string;
56
+ schemaAccessible: boolean;
57
+ endpointResponsive: boolean;
58
+ };
59
+ mcp?: {
60
+ endpoint: string;
61
+ schemaAccessible: boolean;
62
+ };
63
+ a2a?: {
64
+ agentCard: string;
65
+ agentCardAccessible: boolean;
66
+ };
67
+ };
68
+ }
69
+
70
+ /**
71
+ * REST API simulation results
72
+ */
73
+ export interface RestApiSimulationResult {
74
+ success: boolean;
75
+ steps: SimulationStepResult[];
76
+ schemaLoaded: boolean;
77
+ endpointAccessible: boolean;
78
+ sampleOperations: OperationTestResult[];
79
+ }
80
+
81
+ /**
82
+ * Operation test result from REST API
83
+ */
84
+ export interface OperationTestResult {
85
+ operation: string;
86
+ method: string;
87
+ path: string;
88
+ status: SimulationStepStatus;
89
+ message: string;
90
+ responseCode?: number;
91
+ }
92
+
93
+ /**
94
+ * Checkout simulation result
95
+ */
96
+ export interface CheckoutSimulationResult {
97
+ success: boolean;
98
+ steps: SimulationStepResult[];
99
+ canCreateCheckout: boolean;
100
+ checkoutSchemaValid: boolean;
101
+ orderFlowSupported: boolean;
102
+ fulfillmentSupported: boolean;
103
+ }
104
+
105
+ /**
106
+ * Payment readiness result
107
+ */
108
+ export interface PaymentReadinessResult {
109
+ success: boolean;
110
+ steps: SimulationStepResult[];
111
+ handlersFound: number;
112
+ webhookVerifiable: boolean;
113
+ signingKeyValid: boolean;
114
+ }
115
+
116
+ /**
117
+ * Overall AI readiness simulation result
118
+ */
119
+ export interface AgentSimulationResult {
120
+ ok: boolean;
121
+ domain: string;
122
+ simulatedAt: string;
123
+ durationMs: number;
124
+
125
+ // Overall scores (0-100) and grade (A-F)
126
+ overallScore: number;
127
+ grade: 'A' | 'B' | 'C' | 'D' | 'F';
128
+
129
+ // Individual flow results
130
+ discovery: DiscoveryFlowResult;
131
+ capabilities: CapabilityInspectionResult[];
132
+ services: ServiceInspectionResult[];
133
+ restApi?: RestApiSimulationResult;
134
+ checkout?: CheckoutSimulationResult;
135
+ payment?: PaymentReadinessResult;
136
+
137
+ // Summary
138
+ summary: {
139
+ totalSteps: number;
140
+ passedSteps: number;
141
+ failedSteps: number;
142
+ warningSteps: number;
143
+ skippedSteps: number;
144
+ };
145
+
146
+ // Recommendations
147
+ recommendations: string[];
148
+ }
149
+
150
+ /**
151
+ * Simulation options
152
+ */
153
+ export interface SimulationOptions {
154
+ timeoutMs?: number;
155
+ skipRestApiTest?: boolean;
156
+ skipSchemaValidation?: boolean;
157
+ testCheckoutFlow?: boolean;
158
+ verbose?: boolean;
159
+ }
160
+
161
+ /**
162
+ * Default simulation options
163
+ */
164
+ export const DEFAULT_SIMULATION_OPTIONS: Required<SimulationOptions> = {
165
+ timeoutMs: 30000,
166
+ skipRestApiTest: false,
167
+ skipSchemaValidation: false,
168
+ testCheckoutFlow: true,
169
+ verbose: false,
170
+ };
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Generator Types for UCP Profile Generator
3
+ */
4
+
5
+ import type { Environment, ProfileStatus } from './ucp-profile.js';
6
+
7
+ // Merchant information
8
+ export interface MerchantInfo {
9
+ merchantId: string;
10
+ primaryDomain: string;
11
+ displayName?: string;
12
+ environment?: Environment;
13
+ }
14
+
15
+ // Transport configuration inputs
16
+ export interface TransportConfig {
17
+ rest?: {
18
+ endpoint: string;
19
+ schemaUrl?: string; // Override default
20
+ };
21
+ mcp?: {
22
+ endpoint: string;
23
+ schemaUrl?: string;
24
+ };
25
+ a2a?: {
26
+ agentCardUrl: string;
27
+ };
28
+ embedded?: {
29
+ schemaUrl: string;
30
+ };
31
+ }
32
+
33
+ // Capability selection (based on official UCP spec)
34
+ export interface CapabilitySelection {
35
+ checkout: boolean; // Default: true
36
+ order: boolean; // Requires signing keys
37
+ fulfillment: boolean; // Extension of order
38
+ discount: boolean; // Extension
39
+ payment?: boolean; // Payment capability
40
+ buyerConsent?: boolean; // Buyer consent capability
41
+ customCapabilities?: CustomCapability[];
42
+ }
43
+
44
+ // Custom/vendor capability
45
+ export interface CustomCapability {
46
+ namespace: string; // e.g., "com.myvendor"
47
+ name: string; // e.g., "custom-feature"
48
+ version: string;
49
+ specUrl: string;
50
+ schemaUrl: string;
51
+ extendsCapability?: string;
52
+ }
53
+
54
+ // Security configuration
55
+ export interface SecurityConfig {
56
+ generateSigningKeys: boolean;
57
+ signingKeyAlgorithm?: 'ES256' | 'RS256';
58
+ uploadedPublicKey?: string; // PEM or JWK format
59
+ }
60
+
61
+ // Complete generator input
62
+ export interface GeneratorInput {
63
+ merchant: MerchantInfo;
64
+ transport: TransportConfig;
65
+ capabilities: CapabilitySelection;
66
+ security?: SecurityConfig;
67
+ ucpVersion?: string; // Override default version
68
+ }
69
+
70
+ // Generator output artifacts
71
+ export interface GeneratorOutput {
72
+ profile: object; // The UCP profile JSON
73
+ profileJson: string; // Formatted JSON string
74
+ installInstructions: string; // Markdown instructions
75
+ validationReport?: object; // Initial validation
76
+ signingKeyPair?: { // If keys were generated
77
+ publicKey: object; // JWK public key
78
+ privateKey: string; // PEM private key (for merchant to store securely)
79
+ };
80
+ }
81
+
82
+ // Hosting mode options
83
+ export type HostingMode = 'static' | 'edge-worker' | 'reverse-proxy';
84
+
85
+ // Hosting target platforms
86
+ export type HostingPlatform =
87
+ | 'nginx'
88
+ | 'apache'
89
+ | 'vercel'
90
+ | 'netlify'
91
+ | 'cloudflare-worker'
92
+ | 'cloudflare-pages'
93
+ | 's3-cloudfront'
94
+ | 'generic';
95
+
96
+ // Hosting configuration
97
+ export interface HostingConfig {
98
+ mode: HostingMode;
99
+ platform?: HostingPlatform;
100
+ merchantId: string;
101
+ merchantDomain: string;
102
+ hostedProfileUrl?: string; // For edge/proxy modes
103
+ }
104
+
105
+ // Install artifact
106
+ export interface InstallArtifact {
107
+ filename: string;
108
+ content: string;
109
+ contentType: 'json' | 'javascript' | 'nginx' | 'apache' | 'markdown';
110
+ description: string;
111
+ }
112
+
113
+ // Database models (for API service)
114
+ export interface MerchantRecord {
115
+ id: string;
116
+ primaryDomain: string;
117
+ displayName?: string;
118
+ createdAt: Date;
119
+ updatedAt: Date;
120
+ }
121
+
122
+ export interface ProfileRecord {
123
+ id: string;
124
+ merchantId: string;
125
+ versionTag: string;
126
+ ucpVersion: string;
127
+ jsonBody: object;
128
+ status: ProfileStatus;
129
+ createdAt: Date;
130
+ updatedAt: Date;
131
+ }
132
+
133
+ export interface ValidationRunRecord {
134
+ id: string;
135
+ profileId: string;
136
+ mode: 'draft' | 'remote';
137
+ result: object;
138
+ ok: boolean;
139
+ createdAt: Date;
140
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Central export for all UCP Profile Manager types
3
+ */
4
+
5
+ export * from './ucp-profile.js';
6
+ export * from './validation.js';
7
+ export * from './generator.js';
@@ -0,0 +1,140 @@
1
+ /**
2
+ * UCP (Universal Commerce Protocol) Profile Types
3
+ * Based on https://ucp.dev/specification/overview/
4
+ */
5
+
6
+ // Current UCP version
7
+ export const CURRENT_UCP_VERSION = '2026-01-11';
8
+
9
+ // Transport binding types
10
+ export interface RestTransport {
11
+ schema: string; // OpenAPI schema URL
12
+ endpoint: string; // REST API endpoint (https, no trailing slash)
13
+ }
14
+
15
+ export interface McpTransport {
16
+ schema: string; // MCP schema URL
17
+ endpoint: string; // MCP endpoint URL
18
+ }
19
+
20
+ export interface A2aTransport {
21
+ agentCard: string; // A2A agent card URL
22
+ }
23
+
24
+ export interface EmbeddedTransport {
25
+ schema: string; // Embedded schema URL
26
+ }
27
+
28
+ // Service definition with transport bindings
29
+ export interface UcpService {
30
+ version: string;
31
+ spec: string;
32
+ rest?: RestTransport;
33
+ mcp?: McpTransport;
34
+ a2a?: A2aTransport;
35
+ embedded?: EmbeddedTransport;
36
+ }
37
+
38
+ // Capability definition
39
+ export interface UcpCapability {
40
+ name: string; // e.g., "dev.ucp.shopping.checkout"
41
+ version: string; // e.g., "2026-01-11"
42
+ spec: string; // Specification URL
43
+ schema: string; // JSON Schema URL
44
+ extends?: string; // Parent capability for extensions
45
+ config?: Record<string, unknown>; // Capability-specific settings
46
+ }
47
+
48
+ // JWK (JSON Web Key) for signing
49
+ export interface JwkKey {
50
+ kty: string; // Key type (e.g., "EC", "RSA")
51
+ kid: string; // Key ID
52
+ use?: string; // Key use (e.g., "sig")
53
+ alg?: string; // Algorithm (e.g., "ES256")
54
+ crv?: string; // Curve (for EC keys)
55
+ x?: string; // X coordinate (for EC keys)
56
+ y?: string; // Y coordinate (for EC keys)
57
+ n?: string; // Modulus (for RSA keys)
58
+ e?: string; // Exponent (for RSA keys)
59
+ }
60
+
61
+ // Signing keys - array of JWK public keys at root level
62
+ export type SigningKeys = JwkKey[];
63
+
64
+ // Payment handler definition
65
+ export interface PaymentHandler {
66
+ id: string; // Handler identifier
67
+ name: string; // Display name
68
+ version: string; // Handler version (YYYY-MM-DD)
69
+ spec: string; // Handler specification URL
70
+ config_schema?: string; // Configuration schema URL
71
+ instrument_schemas?: string[]; // Payment instrument schemas
72
+ config?: Record<string, unknown>; // Handler-specific config
73
+ }
74
+
75
+ // Payment configuration
76
+ export interface PaymentConfig {
77
+ handlers: PaymentHandler[];
78
+ }
79
+
80
+ // Main UCP object within profile
81
+ export interface UcpObject {
82
+ version: string;
83
+ services: Record<string, UcpService>;
84
+ capabilities: UcpCapability[];
85
+ }
86
+
87
+ // Complete UCP Business Profile (/.well-known/ucp)
88
+ export interface UcpProfile {
89
+ ucp: UcpObject;
90
+ payment?: PaymentConfig; // Payment handlers configuration
91
+ signing_keys?: SigningKeys; // JWK public keys for webhook verification
92
+ // Additional vendor extensions can be added as siblings
93
+ [key: string]: unknown;
94
+ }
95
+
96
+ // Known capability namespaces
97
+ export const CAPABILITY_NAMESPACES = {
98
+ UCP_OFFICIAL: 'dev.ucp.',
99
+ VENDOR_PREFIX: 'com.',
100
+ } as const;
101
+
102
+ // Known UCP capabilities (from official spec)
103
+ export const KNOWN_CAPABILITIES = {
104
+ CHECKOUT: 'dev.ucp.shopping.checkout',
105
+ ORDER: 'dev.ucp.shopping.order',
106
+ PAYMENT: 'dev.ucp.shopping.payment',
107
+ PAYMENT_DATA: 'dev.ucp.shopping.payment_data',
108
+ FULFILLMENT: 'dev.ucp.shopping.fulfillment',
109
+ DISCOUNT: 'dev.ucp.shopping.discount',
110
+ BUYER_CONSENT: 'dev.ucp.shopping.buyer_consent',
111
+ } as const;
112
+
113
+ // Known UCP services
114
+ export const KNOWN_SERVICES = {
115
+ SHOPPING: 'dev.ucp.shopping',
116
+ } as const;
117
+
118
+ // Default URLs for UCP official resources
119
+ export const UCP_DEFAULTS = {
120
+ SPEC_BASE: 'https://ucp.dev/specification/',
121
+ SCHEMA_BASE: 'https://ucp.dev/schemas/',
122
+ SERVICE_SCHEMA_BASE: 'https://ucp.dev/services/',
123
+
124
+ // Default schema URLs
125
+ SHOPPING_REST_SCHEMA: 'https://ucp.dev/services/shopping/rest.openapi.json',
126
+ CHECKOUT_SPEC: 'https://ucp.dev/specification/checkout/',
127
+ CHECKOUT_SCHEMA: 'https://ucp.dev/schemas/shopping/checkout.json',
128
+ ORDER_SPEC: 'https://ucp.dev/specification/order/',
129
+ ORDER_SCHEMA: 'https://ucp.dev/schemas/shopping/order.json',
130
+ FULFILLMENT_SPEC: 'https://ucp.dev/specification/fulfillment/',
131
+ FULFILLMENT_SCHEMA: 'https://ucp.dev/schemas/shopping/fulfillment.json',
132
+ DISCOUNT_SPEC: 'https://ucp.dev/specification/discount/',
133
+ DISCOUNT_SCHEMA: 'https://ucp.dev/schemas/shopping/discount.json',
134
+ } as const;
135
+
136
+ // Environment types
137
+ export type Environment = 'production' | 'staging' | 'development';
138
+
139
+ // Profile status
140
+ export type ProfileStatus = 'draft' | 'published';
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Validation Types for UCP Profile Validator
3
+ */
4
+
5
+ // Validation severity levels
6
+ export type ValidationSeverity = 'error' | 'warn' | 'info';
7
+
8
+ // Validation error codes
9
+ export const ValidationErrorCodes = {
10
+ // Structural errors
11
+ MISSING_UCP_OBJECT: 'UCP_MISSING_ROOT',
12
+ MISSING_VERSION: 'UCP_MISSING_VERSION',
13
+ INVALID_VERSION_FORMAT: 'UCP_INVALID_VERSION_FORMAT',
14
+ MISSING_SERVICES: 'UCP_MISSING_SERVICES',
15
+ MISSING_CAPABILITIES: 'UCP_MISSING_CAPABILITIES',
16
+ INVALID_SERVICE_STRUCTURE: 'UCP_INVALID_SERVICE',
17
+ INVALID_CAPABILITY_STRUCTURE: 'UCP_INVALID_CAPABILITY',
18
+
19
+ // UCP rules errors
20
+ NS_ORIGIN_MISMATCH: 'UCP_NS_ORIGIN_MISMATCH',
21
+ ORPHANED_EXTENSION: 'UCP_ORPHANED_EXTENSION',
22
+ ENDPOINT_NOT_HTTPS: 'UCP_ENDPOINT_NOT_HTTPS',
23
+ ENDPOINT_TRAILING_SLASH: 'UCP_ENDPOINT_TRAILING_SLASH',
24
+ MISSING_SIGNING_KEYS: 'UCP_MISSING_SIGNING_KEYS',
25
+ INVALID_SIGNING_KEY: 'UCP_INVALID_SIGNING_KEY',
26
+
27
+ // Network validation errors
28
+ PROFILE_FETCH_FAILED: 'UCP_PROFILE_FETCH_FAILED',
29
+ SCHEMA_FETCH_FAILED: 'UCP_SCHEMA_FETCH_FAILED',
30
+ SCHEMA_NOT_SELF_DESCRIBING: 'UCP_SCHEMA_NOT_SELF_DESCRIBING',
31
+ SCHEMA_NAME_MISMATCH: 'UCP_SCHEMA_NAME_MISMATCH',
32
+ SCHEMA_VERSION_MISMATCH: 'UCP_SCHEMA_VERSION_MISMATCH',
33
+ PRIVATE_IP_ENDPOINT: 'UCP_PRIVATE_IP_ENDPOINT',
34
+ } as const;
35
+
36
+ export type ValidationErrorCode = typeof ValidationErrorCodes[keyof typeof ValidationErrorCodes];
37
+
38
+ // Single validation issue
39
+ export interface ValidationIssue {
40
+ severity: ValidationSeverity;
41
+ code: ValidationErrorCode;
42
+ path: string; // JSON path (e.g., "$.ucp.capabilities[0].schema")
43
+ message: string; // Human-readable message
44
+ hint?: string; // Suggestion for fixing
45
+ }
46
+
47
+ // Validation report
48
+ export interface ValidationReport {
49
+ ok: boolean;
50
+ profile_url?: string; // For remote validation
51
+ ucp_version?: string;
52
+ issues: ValidationIssue[];
53
+ validated_at: string; // ISO timestamp
54
+ validation_mode: ValidationMode;
55
+ sdk_validation?: { // Official SDK validation info
56
+ validated: boolean; // Whether SDK validation passed
57
+ sdk_version: string; // @ucp-js/sdk version used
58
+ compliant: boolean; // Whether profile is SDK-compliant
59
+ };
60
+ }
61
+
62
+ // Validation modes
63
+ export type ValidationMode = 'structural' | 'rules' | 'network' | 'full';
64
+
65
+ // Validation options
66
+ export interface ValidationOptions {
67
+ mode?: ValidationMode;
68
+ skipNetworkChecks?: boolean;
69
+ timeoutMs?: number;
70
+ cacheTtlMs?: number;
71
+ }
72
+
73
+ // Schema cache entry
74
+ export interface SchemaCacheEntry {
75
+ url: string;
76
+ etag?: string;
77
+ fetchedAt: string;
78
+ body: Record<string, unknown>;
79
+ expiresAt: string;
80
+ }
81
+
82
+ // Remote fetch result
83
+ export interface FetchResult<T> {
84
+ success: boolean;
85
+ data?: T;
86
+ error?: string;
87
+ statusCode?: number;
88
+ etag?: string;
89
+ }