"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.workerWorkflowFirstRunSchema = exports.workerWorkflowScheduledRunSchema = exports.workerWorkflowRecurringAutoStopSchema = exports.workerWorkflowScheduleSchema = void 0;
exports.buildWorkerWorkflowAutomationIntentPromptRules = buildWorkerWorkflowAutomationIntentPromptRules;
exports.buildWorkerWorkflowSchedulePromptRules = buildWorkerWorkflowSchedulePromptRules;
exports.validateWorkerWorkflowScheduleSemanticRules = validateWorkerWorkflowScheduleSemanticRules;
const zod_1 = require("zod");
const recurring_1 = require("../workflows/recurring");
const scheduled_run_1 = require("../workflows/scheduled-run");
const schedule_primitives_1 = require("../workflows/schedule-primitives");
const types_1 = require("../workflows/types");
const validation_issues_1 = require("./validation-issues");
exports.workerWorkflowScheduleSchema = zod_1.z
    .discriminatedUnion("mode", [
    zod_1.z
        .object({
        mode: zod_1.z.literal("off").describe("Disable recurrence."),
        value: zod_1.z.null().describe("No schedule value."),
    })
        .strict(),
    zod_1.z
        .object({
        mode: zod_1.z.enum(["every", "cron"]).describe("Schedule mode."),
        value: zod_1.z.string().min(1).describe("Schedule expression."),
    })
        .strict(),
])
    .describe("Workflow schedule.");
exports.workerWorkflowRecurringAutoStopSchema = zod_1.z
    .discriminatedUnion("mode", [
    zod_1.z
        .object({
        mode: zod_1.z.literal("off"),
    })
        .strict(),
    zod_1.z
        .object({
        mode: zod_1.z.literal("update"),
        stopAt: zod_1.z
            .string()
            .min(1)
            .refine(schedule_primitives_1.isWorkflowRunAtInputShape, "Invalid stop-at value.")
            .optional(),
        stopAfter: zod_1.z
            .string()
            .min(1)
            .refine((value) => (0, schedule_primitives_1.parseWorkflowDurationToMilliseconds)(value) !== null, "Invalid stop-after value.")
            .optional(),
        stopAfterRuns: zod_1.z.number().int().positive().optional(),
    })
        .strict(),
])
    .describe("Recurring auto-stop command.");
exports.workerWorkflowScheduledRunSchema = zod_1.z
    .discriminatedUnion("mode", [
    zod_1.z
        .object({
        mode: zod_1.z.literal("run_at"),
        value: zod_1.z
            .string()
            .min(1)
            .refine(schedule_primitives_1.isWorkflowRunAtInputShape, "Invalid run-at value."),
    })
        .strict(),
    zod_1.z
        .object({
        mode: zod_1.z.literal("run_after"),
        value: zod_1.z
            .string()
            .min(1)
            .refine((value) => (0, schedule_primitives_1.parseWorkflowDurationToMilliseconds)(value) !== null, "Invalid run-after value."),
    })
        .strict(),
])
    .describe("One-shot scheduled run command.");
exports.workerWorkflowFirstRunSchema = zod_1.z
    .discriminatedUnion("mode", [
    zod_1.z
        .object({
        mode: zod_1.z.literal("run_at"),
        value: zod_1.z
            .string()
            .min(1)
            .refine(schedule_primitives_1.isWorkflowRunAtInputShape, "Invalid first-run-at value."),
    })
        .strict(),
    zod_1.z
        .object({
        mode: zod_1.z.literal("run_after"),
        value: zod_1.z
            .string()
            .min(1)
            .refine((value) => (0, schedule_primitives_1.parseWorkflowDurationToMilliseconds)(value) !== null, "Invalid first-run-after value."),
    })
        .strict(),
    zod_1.z
        .object({
        mode: zod_1.z.literal("now"),
        value: zod_1.z.null(),
    })
        .strict(),
])
    .describe("Recurring first-run command.");
function buildWorkerWorkflowAutomationIntentPromptRules(options) {
    return [
        "When workflow option capabilities, value formats, or conflicts are unclear, inspect the repo-local Alpaca skill and relevant alpaca issue create --help output before deciding; do not guess.",
        "Map explicit follow-up issue requests or independent post-completion iteration/improvement requests without an explicit cadence to workflow.overrides.followup.proposalPolicy if_needed, not to a fabricated recurring schedule.",
        "Do not map broad unfinished goals, unmet doneWhen, or work decomposition needs to workflow.overrides.followup proposal fields or, by themselves, to workflow.schedule.",
        "Use workflow.scheduledRun only for explicit one-shot future run-at or run-after requests.",
        "Use workflow.schedule when the prompt gives a cadence or when the work item objective is intrinsically repeated monitoring, freshness maintenance, or cadence-based checking; do not infer schedule only because the goal is broad, ongoing, or multi-step.",
        "When inferring workflow.schedule without an explicit cadence for an intrinsically recurring objective, choose the interval that best supports the work item's objective. Balance required freshness, urgency, expected change frequency, execution cost, worker capacity, and whether the work is finite or ongoing; do not default to 1d or any other cadence without this tradeoff.",
        "If repeated attention would help but no cadence is explicit or justified by the objective, leave workflow.schedule unset and record the manual repeat loop or future checkpoint in the human-facing issue body when drafting an issue.",
        "Use workflow.firstRun only with workflow.schedule every or cron when the first recurring run time is explicit or naturally follows from the requested work.",
        "Use workflow.recurringAutoStop only with a recurring schedule and only when a finite stop condition or ongoing/no-stop intent is justified by the prompt; do not force an auto-stop when the work reads as ongoing.",
        options.includeIssueBodyUnknownsRule === true
            ? "Do not invent arbitrary workflow metadata. When recurring automation is justified by repeated monitoring, freshness, or cadence-based checking but cadence, first-run, or stop conditions are not explicit, infer only the values justified by the objective, urgency, expected change frequency, execution cost, and whether the work is finite or ongoing; record unknowns in the human-facing issue body when drafting an issue."
            : "Do not invent arbitrary workflow metadata. When recurring automation is justified by repeated monitoring, freshness, or cadence-based checking but cadence, first-run, or stop conditions are not explicit, infer only the values justified by the objective, urgency, expected change frequency, execution cost, and whether the work is finite or ongoing; omit fields that are not justified.",
    ];
}
function buildWorkerWorkflowSchedulePromptRules(options) {
    const rules = [
        `workflow.schedule is optional; when present its mode must be one of ${types_1.WORKFLOW_SCHEDULE_MODES.join(", ")} or null.`,
    ];
    if (options.includeScheduledRunRules === true) {
        rules.push("workflow.scheduledRun is optional and represents one-shot run-at or run-after scheduling.");
    }
    if (options.includeFirstRunRules === true) {
        rules.push("workflow.firstRun is optional and controls the first run of a recurring schedule.", "workflow.firstRun must not be combined with workflow.scheduledRun.");
    }
    rules.push("workflow.recurringAutoStop is optional and controls recurring auto-stop behavior.", options.includeRecurringAutoStopConflictRule === true
        ? "workflow.recurringAutoStop may include stopAt, stopAfter, stopAfterRuns, or mode off; do not combine stopAt with stopAfter."
        : "workflow.recurringAutoStop may include stopAt, stopAfter, stopAfterRuns, or mode off.");
    if (options.includeAcceptedAtRule === true) {
        rules.push("Use acceptedAt as the current time when interpreting workflow.scheduledRun and workflow.firstRun values.", "run_at values must be ISO-like future datetimes; values without a time zone use displayTimeZone.", "run_after and every values must use compact positive duration strings composed of supported units: ms, s, m, h, d, and w.");
    }
    return rules;
}
function validateWorkerWorkflowScheduleSemanticRules(workflow, input, issues) {
    validateWorkflowSchedule(workflow.schedule, issues);
    validateRecurringAutoStop(workflow, issues);
    validateScheduledRun(workflow, input, issues);
    validateFirstRun(workflow, input, issues);
}
function validateWorkflowSchedule(schedule, issues) {
    if (schedule === undefined || schedule === null || schedule.mode === "off") {
        return;
    }
    const nextRunAt = (0, recurring_1.resolveNextRunAtFromAcceptedAt)(schedule, "2026-01-01T00:00:00.000Z", "UTC");
    if (nextRunAt !== null) {
        return;
    }
    (0, validation_issues_1.addWorkerSemanticValidationIssue)(issues, {
        path: ["workflow", "schedule", "value"],
        message: `workflow.schedule.value must be a valid ${schedule.mode} schedule expression.`,
    });
}
function validateRecurringAutoStop(workflow, issues) {
    const autoStop = workflow.recurringAutoStop;
    if (autoStop === undefined || autoStop === null || autoStop.mode === "off") {
        return;
    }
    if (autoStop.stopAt === undefined &&
        autoStop.stopAfter === undefined &&
        autoStop.stopAfterRuns === undefined) {
        (0, validation_issues_1.addWorkerSemanticValidationIssue)(issues, {
            path: ["workflow", "recurringAutoStop"],
            message: "workflow.recurringAutoStop must include at least one stop condition.",
        });
    }
    if (autoStop.stopAt !== undefined && autoStop.stopAfter !== undefined) {
        (0, validation_issues_1.addWorkerSemanticValidationIssue)(issues, {
            path: ["workflow", "recurringAutoStop"],
            message: "workflow.recurringAutoStop must not combine stopAt and stopAfter.",
        });
    }
    if (workflow.schedule === undefined ||
        workflow.schedule === null ||
        workflow.schedule.mode === "off") {
        (0, validation_issues_1.addWorkerSemanticValidationIssue)(issues, {
            path: ["workflow", "recurringAutoStop"],
            message: "workflow.recurringAutoStop requires a recurring schedule.",
        });
    }
}
function validateScheduledRun(workflow, input, issues) {
    if (workflow.scheduledRun !== undefined && workflow.scheduledRun !== null) {
        if (workflow.schedule !== undefined && workflow.schedule !== null) {
            (0, validation_issues_1.addWorkerSemanticValidationIssue)(issues, {
                path: ["workflow", "scheduledRun"],
                message: "workflow.scheduledRun must not be combined with workflow.schedule.",
            });
        }
        if ((0, scheduled_run_1.materializeScheduledRunCommand)({
            command: workflow.scheduledRun,
            acceptedAt: input.acceptedAt,
            displayTimeZone: input.displayTimeZone,
        }) === null) {
            (0, validation_issues_1.addWorkerSemanticValidationIssue)(issues, {
                path: ["workflow", "scheduledRun"],
                message: "workflow.scheduledRun must resolve to a future run time from acceptedAt.",
            });
        }
    }
}
function validateFirstRun(workflow, input, issues) {
    if (workflow.firstRun === undefined || workflow.firstRun === null) {
        return;
    }
    if (workflow.schedule === undefined ||
        workflow.schedule === null ||
        workflow.schedule.mode === "off") {
        (0, validation_issues_1.addWorkerSemanticValidationIssue)(issues, {
            path: ["workflow", "firstRun"],
            message: "workflow.firstRun requires workflow.schedule every or cron.",
        });
        return;
    }
    if (workflow.scheduledRun !== undefined && workflow.scheduledRun !== null) {
        (0, validation_issues_1.addWorkerSemanticValidationIssue)(issues, {
            path: ["workflow", "firstRun"],
            message: "workflow.firstRun must not be combined with workflow.scheduledRun.",
        });
    }
    if ((0, recurring_1.resolveInitialRecurringNextRunAt)({
        schedule: workflow.schedule,
        firstRun: workflow.firstRun,
        acceptedAt: input.acceptedAt,
        displayTimeZone: input.displayTimeZone,
    }) === null) {
        (0, validation_issues_1.addWorkerSemanticValidationIssue)(issues, {
            path: ["workflow", "firstRun"],
            message: "workflow.firstRun must resolve to a valid initial recurring run time.",
        });
    }
}
