/**
 * wfrun/schema.mjs — Zod schema for C17 declarative YAML workflows.
 *
 * Defines the shape of a workflow document:
 *   apiVersion: 'aperant.dev/v1'
 *   kind: 'Workflow'
 *   metadata: { id, description? }
 *   inputs: [{ name, required?, default?, description? }]
 *   nodes:  [{ id, kind: 'skill'|'agent'|'tool', depends_on?, outputs?, ... }]
 *
 * Nodes are modeled as a discriminated union on `kind`:
 *   - skill: { skill: <name>, prompt?: <string> }
 *   - agent: { agent: <name>, prompt?: <string> }
 *   - tool:  { run: { command: <apt-tools subcommand>, args: [<string>...] } }
 *
 * Semantic checks that Zod can't express (duplicate ids, dangling depends_on)
 * are performed by parse.mjs after safeParse.
 */
import { z } from 'zod';
/**
 * Slug regex — lowercase ASCII, digits, hyphens; must start with [a-z0-9].
 * Used for workflow ids, node ids, input names, and declared output keys.
 */
export const SLUG_RE = /^[a-z0-9][a-z0-9-]*$/;
const SlugString = z
    .string()
    .regex(SLUG_RE, 'must match /^[a-z0-9][a-z0-9-]*$/ (lowercase, digits, hyphens)');
// Input names and output keys may also use underscores (matches the
// convention seen in apt-tools flag names like `--task-id` vs JSON keys
// like `task_description`).
const IdentifierString = z
    .string()
    .regex(/^[a-z0-9][a-z0-9_-]*$/, 'must match /^[a-z0-9][a-z0-9_-]*$/ (lowercase, digits, hyphens, underscores)');
const InputDefSchema = z
    .object({
    name: IdentifierString,
    required: z.boolean().optional().default(true),
    default: z.string().optional(),
    description: z.string().optional(),
})
    .strict();
const DependsOn = z.array(z.string()).optional().default([]);
const Outputs = z.array(z.string()).optional().default([]);
const SkillNodeSchema = z
    .object({
    id: SlugString,
    kind: z.literal('skill'),
    skill: z.string().min(1),
    prompt: z.string().optional(),
    depends_on: DependsOn,
    outputs: Outputs,
})
    .strict();
const AgentNodeSchema = z
    .object({
    id: SlugString,
    kind: z.literal('agent'),
    agent: z.string().min(1),
    prompt: z.string().optional(),
    depends_on: DependsOn,
    outputs: Outputs,
})
    .strict();
const ToolRunSchema = z
    .object({
    command: z.string().min(1),
    args: z.array(z.string()).optional().default([]),
})
    .strict();
const ToolNodeSchema = z
    .object({
    id: SlugString,
    kind: z.literal('tool'),
    run: ToolRunSchema,
    depends_on: DependsOn,
    outputs: Outputs,
})
    .strict();
export const NodeSchema = z.discriminatedUnion('kind', [
    SkillNodeSchema,
    AgentNodeSchema,
    ToolNodeSchema,
]);
export const WorkflowSchema = z
    .object({
    apiVersion: z.literal('aperant.dev/v1'),
    kind: z.literal('Workflow'),
    metadata: z
        .object({
        id: SlugString,
        description: z.string().optional(),
    })
        .strict(),
    inputs: z.array(InputDefSchema).optional().default([]),
    nodes: z.array(NodeSchema).min(1, 'workflow must declare at least one node'),
})
    .strict();
//# sourceMappingURL=schema.mjs.map