import { z } from 'zod';
// Design principle: strict on semantics (wired/testable), loose on presentation (type, component paths).
// The type vocabulary is a hint for downstream consumers, not a closed taxonomy — UI elements are
// too diverse to enumerate. Schemas should constrain meaning, not style.
const TestableEnum = z.enum(['testable', 'observable', 'blocked']);
// `wired` is semantic: true = real backend connection, "stubbed"/"partial" = callback exists but incomplete,
// false = pure mock/display-only. Accept both "stubbed" and "partial" as equivalent partial-wiring signals.
const WiredUnion = z.union([
    z.literal(true),
    z.literal(false),
    z.literal('stubbed'),
    z.literal('partial'),
]);
const IdSchema = z.string().regex(/^[a-z0-9-]+$/, {
    message: 'id must contain only lowercase letters, digits, and hyphens',
});
// Component paths are strings like "path/to/file.tsx:42". Agents sometimes emit objects
// ({ path, lines, description }) — those must be normalized to strings before validation.
// Keeping this strict (string-only) lets us preserve JSON Schema generation via z.toJSONSchema().
const ComponentRef = z.string().min(1);
export const SubFeatureSchema = z.object({
    id: IdSchema,
    name: z.string().min(1),
    component: ComponentRef.optional(),
    type: z.string().min(1),
    wired: WiredUnion,
    handler: z.string().optional(),
    default: z.unknown().optional(),
    range: z.unknown().optional(),
    options: z.unknown().optional(),
    shortcut: z.string().optional(),
    testable: TestableEnum.optional(),
    test_hint: z.string().optional(),
});
export const FeatureGroupSchema = z.object({
    id: IdSchema,
    name: z.string().min(1),
    component: ComponentRef.optional(),
    sub_features: z.array(SubFeatureSchema).default([]),
});
export const FeatureRegistrySchema = z.object({
    area: z.string().min(1),
    route: z.string().min(1),
    components: z.array(ComponentRef).default([]),
    last_scanned: z.string().regex(/^\d{4}-\d{2}-\d{2}(T[\d:.Z+-]+)?$/, {
        message: 'last_scanned must be a date string in YYYY-MM-DD or full ISO 8601 format',
    }),
    features: z.array(FeatureGroupSchema),
});
// Validator — thin wrapper returning zod's discriminated union { success: true, data } | { success: false, error }
export function validateFeatureRegistry(data) {
    return FeatureRegistrySchema.safeParse(data);
}
// Pre-computed JSON Schema for use in LLM prompt injection
export const featureRegistryJsonSchema = z.toJSONSchema(FeatureRegistrySchema);
//# sourceMappingURL=feature-registry.js.map