"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WORKER_TEMPLATE_AUTHORING_GUIDE_RULES = exports.WORKFLOW_TEMPLATE_SOURCE_REQUEST_RULE = exports.WORKER_TEMPLATE_BODY_MARKDOWN_RULE = exports.WORKER_TEMPLATE_DESCRIPTION_RULE = exports.WORKER_TEMPLATE_LANGUAGE_RULE = exports.WORKER_TEMPLATE_REQUIRED_CAPABILITY_RULES = exports.WORKER_TEMPLATE_CONTENT_SCHEMA_SHAPE = void 0;
exports.normalizeWorkerTemplateContentInput = normalizeWorkerTemplateContentInput;
exports.buildLocalizedWorkerTemplateExampleContent = buildLocalizedWorkerTemplateExampleContent;
exports.buildWorkerTemplateContract = buildWorkerTemplateContract;
exports.buildWorkerWorkflowTemplateRecord = buildWorkerWorkflowTemplateRecord;
exports.buildWorkerWorkflowTemplateCatalog = buildWorkerWorkflowTemplateCatalog;
exports.formatWorkerTemplateStructureIssueMessage = formatWorkerTemplateStructureIssueMessage;
exports.startsWithWorkerTemplateFrontmatter = startsWithWorkerTemplateFrontmatter;
exports.validateWorkerTemplateRequiredSkills = validateWorkerTemplateRequiredSkills;
exports.validateWorkerTemplateRequiredMcp = validateWorkerTemplateRequiredMcp;
exports.validateWorkerTemplateContentSemanticRules = validateWorkerTemplateContentSemanticRules;
exports.validateWorkerTemplateBodyStructure = validateWorkerTemplateBodyStructure;
const zod_1 = require("zod");
const branding_1 = require("../core/branding");
const required_mcp_1 = require("../workflows/required-mcp");
const required_skills_1 = require("../workflows/required-skills");
const template_registry_1 = require("../workflows/template-registry");
const validation_1 = require("../workflows/validation");
const structured_contract_support_1 = require("./structured-contract-support");
const validation_issues_1 = require("./validation-issues");
exports.WORKER_TEMPLATE_CONTENT_SCHEMA_SHAPE = {
    description: zod_1.z
        .string()
        .min(1)
        .nullable()
        .describe("Short workflow template description or null."),
    requires: zod_1.z
        .object({
        skills: zod_1.z
            .array(zod_1.z.string().min(1))
            .describe("Required skill refs that must exist before this workflow can run."),
        mcp: zod_1.z
            .array(zod_1.z.string().min(1))
            .describe("Required MCP refs that must be configured before this workflow can run."),
    })
        .strict()
        .describe("Workflow capabilities required before this workflow can run."),
    targets: zod_1.z
        .array(zod_1.z.enum(["issue", "pull_request", "unplanned", "followup"]))
        .min(1)
        .describe("Workflow run targets where this template can be selected."),
    autoSelect: zod_1.z
        .boolean()
        .describe("Whether this template is eligible for automatic selection."),
    body: zod_1.z
        .string()
        .min(1)
        .describe("Markdown workflow template body without frontmatter."),
};
function normalizeWorkerTemplateContentInput(input) {
    return {
        description: input.description,
        requiredSkills: input.requires.skills,
        requiredMcp: input.requires.mcp,
        targets: input.targets,
        autoSelect: input.autoSelect,
        body: input.body,
    };
}
exports.WORKER_TEMPLATE_REQUIRED_CAPABILITY_RULES = [
    "requires.skills must be an array of usable refs from alpaca skill list. Use [] when no specific skills are required.",
    "requires.skills declares capabilities required to run the workflow; it is not an instruction to install or create skills.",
    "requires.mcp must be an array of MCP refs from alpaca mcp list/verify. Use [] when no MCP server is required.",
    "requires.mcp declares tool connections required to run the workflow; it is not an instruction to install or configure MCP servers inside normal workflow work.",
];
exports.WORKER_TEMPLATE_LANGUAGE_RULE = "Write generated human-facing text in the configured output language, including description, Markdown body prose, document titles, and section headings. Do not translate JSON field names, enum/control values, IDs, paths, skill refs, MCP refs or tool refs, requires, skills, mcp, targets, autoSelect, @workflow selectors, commands, code, URLs, or other machine-controlled values.";
exports.WORKER_TEMPLATE_DESCRIPTION_RULE = "description must be a non-empty string or null. When provided, it must briefly state when this workflow template should be selected for each declared target. For multi-target templates, distinguish the issue, pull_request, unplanned, and followup use cases. For followup targets, describe the independent post-completion condition that makes this template appropriate. Do not describe recurring as a target; recurring behavior uses issue schedule state.";
exports.WORKER_TEMPLATE_BODY_MARKDOWN_RULE = "body must be markdown only and must not include YAML frontmatter.";
exports.WORKFLOW_TEMPLATE_SOURCE_REQUEST_RULE = "When a prompt comes from a missing-workflow-template setup issue, treat the parent/source request as the reusable work type. Do not draft or update a workflow for the setup issue, CLI command, or workflow template authoring guidance unless the parent/source request is itself workflow-template authoring.";
exports.WORKER_TEMPLATE_AUTHORING_GUIDE_RULES = [
    "Follow this template contract for workflow reference semantics, handoff rules, success criteria, and repository-fact guardrails. Use the workflow-common and workflow-create system prompts for repository-specific guidance.",
    "Workflow body sections for reusable goal or intent, rules, process guidance, human handoff boundaries, and success criteria are recommended when useful, but write heading text in the configured output language and do not add mechanical sections just to satisfy a format.",
    "Workflow body should connect the reusable primary intent to deliverable quality and observable completion evidence so workflow_plan can derive concrete doneWhen items.",
    "For broad reusable workflows, body should describe responsibility boundaries, dependency order, expected deliverables, evidence bundles, review or integration boundaries, and final synthesis expectations so workflow_plan can decide same-issue tasks versus child issues without hard-coded one-off child_issue steps.",
    "For reusable improvement or optimization workflows, body should define the evaluation contract pattern: baseline or current-state discovery, metric or evaluation axis, source of truth, measurement window policy, target or decision threshold policy, guardrails or non-goals, and claim-boundary reporting.",
    `@workflow selectors must be root-relative to ${branding_1.WORKFLOW_TEMPLATES_DIRECTORY}, normalized .md paths, and contain no whitespace.`,
    `Use plain ${branding_1.WORKFLOW_TEMPLATES_DIRECTORY}/foo.md document paths for reference guidance that should not create a separate planned step; use @workflow only when a separate nested workflow step is intended.`,
    "Before adding a nested workflow module, check whether an existing workflow template can be reused or updated. Create a new module only for a distinct reusable responsibility boundary with its own evidence bundle, review or integration boundary, or execution-readiness contract.",
    "Reference each intended nested workflow module with at most one standalone @workflow call site in the owning template. Describe conditional applicability in prose around that one call site instead of repeating the directive in rules and process sections.",
    "Do not split workflow templates by issue step, file, bullet, phase label, or convenience alone. Keep guidance in the current template when it only needs to be read as shared context, cross-cutting rules, or optional reference material.",
    "For repository-local workflow template paths, prefer <domain>/<role>-<scope>.md. Reuse an existing domain folder for the same purpose before creating a new folder, and do not create synonym folders for the same domain.",
    "The CLI writes the decision's requires.skills and requires.mcp arrays to workflow template frontmatter under requires.skills and requires.mcp.",
];
function buildLocalizedWorkerTemplateExampleContent(locale) {
    switch (locale) {
        case "ja":
            return buildJapaneseWorkerTemplateExampleContent();
        case "zh":
            return buildChineseWorkerTemplateExampleContent();
        case "en":
            return buildEnglishWorkerTemplateExampleContent();
    }
}
function buildJapaneseWorkerTemplateExampleContent() {
    return {
        description: "範囲が定まった変更をレビューし検証する再利用可能なテンプレート",
        body: [
            "# レビューフロー",
            "",
            "## 目的",
            "",
            "範囲が定まった変更をレビューし、完了判断に必要な検証証跡を残す。",
            "",
            "## ルール",
            "",
            "### やること",
            "",
            "- 確認済みの作業範囲とリポジトリ文脈の中で進める。",
            "- 判断、検証、ブロッカー、残リスクの証跡を記録する。",
            "",
            "### やらないこと",
            "",
            "- リポジトリの事実、コマンド、サービス、制約を推測で補わない。",
            "- 別のフォローアップまたはネストしたワークフローに分けるべき作業を混ぜない。",
            "",
            "## 必須プロセス",
            "",
            "### 1. 範囲を再確認する",
            "",
            "- 編集前に issue、最新コメント、現在の差分を読む。",
            "- 対象範囲、対象外、変更してはいけない境界を明確にする。",
            "",
            "### 2. 検証する",
            "",
            "- 変更した挙動と影響箇所を証明できる最小の確認を実行する。",
            "- 実行できない確認は理由と残リスクを明記する。",
            "",
            "## 人へ引き継ぐ条件",
            "",
            "- 要件が衝突している、または安全な変更境界が不明な場合。",
            "- 認証情報、外部サービス、プロダクト判断が必要な場合。",
            "",
            "## 成功条件",
            "",
            "- 変更が issue の範囲と一致している。",
            "- 関連するテストまたは確認が通るか、未実行の確認と理由が明記されている。",
        ].join("\n"),
    };
}
function buildChineseWorkerTemplateExampleContent() {
    return {
        description: "用于审查并验证限定范围变更的可复用模板",
        body: [
            "# 审查流程",
            "",
            "## 目标",
            "",
            "审查范围明确的变更，并留下足以支持完成判断的验证证据。",
            "",
            "## 规则",
            "",
            "### 要做",
            "",
            "- 将所有步骤保持在已确认的工作范围和仓库上下文内。",
            "- 记录决策、验证、阻塞项和剩余风险的证据。",
            "",
            "### 不要做",
            "",
            "- 不要编造仓库事实、命令、服务或约束。",
            "- 不要混入应拆分为后续事项或嵌套工作流的无关工作。",
            "",
            "## 必要流程",
            "",
            "### 1. 重新确认范围",
            "",
            "- 编辑前阅读 issue、最新人工评论和当前差异。",
            "- 明确范围内工作、范围外工作以及不得变更的边界。",
            "",
            "### 2. 验证",
            "",
            "- 运行能证明变更行为和影响点的最小检查。",
            "- 对无法运行的检查说明原因和剩余风险。",
            "",
            "## 需要人工介入时",
            "",
            "- 需求冲突或安全变更边界不明确。",
            "- 需要凭据、外部服务或产品判断。",
            "",
            "## 成功标准",
            "",
            "- 变更符合 issue 范围。",
            "- 相关测试或检查通过，或明确说明未运行的检查及原因。",
        ].join("\n"),
    };
}
function buildEnglishWorkerTemplateExampleContent() {
    return {
        description: "Reusable template for reviewing and verifying scoped changes",
        body: [
            "# Review Flow",
            "",
            "## Goal",
            "",
            "Review a scoped change and leave enough verification evidence for a completion decision.",
            "",
            "## Rules",
            "",
            "### Do",
            "",
            "- Keep every step inside the confirmed workflow scope and repository context.",
            "- Record evidence for decisions, verification, blockers, and residual risk.",
            "",
            "### Do Not",
            "",
            "- Do not invent repository facts, commands, services, people, or constraints.",
            "- Do not combine unrelated work that should be split into a follow-up issue or nested workflow.",
            "",
            "## Required Process",
            "",
            "### 1. Reconstruct Scope",
            "",
            "- Read the issue, latest human comments, and current diff before editing.",
            "- State the in-scope work, out-of-scope work, and boundaries that must not be changed.",
            "",
            "### 2. Verify",
            "",
            "- Run the smallest checks that prove the changed behavior and affected integration points.",
            "- Name any checks that cannot be run and explain the remaining risk.",
            "",
            "## Handoff To Human When",
            "",
            "- Requirements conflict or the safe change boundary is unclear.",
            "- Verification needs credentials, services, or product judgment unavailable to the worker.",
            "",
            "## Success Criteria",
            "",
            "- The implemented change matches the issue scope.",
            "- Relevant tests or checks pass, or blocked checks are explicitly named with reasons.",
        ].join("\n"),
    };
}
function buildWorkerTemplateContract(input) {
    return (0, structured_contract_support_1.buildWorkerStructuredContract)({
        schema: input.schema,
        example: input.example,
        rules: input.rules,
    });
}
function buildWorkerWorkflowTemplateRecord(input) {
    const parsed = (0, template_registry_1.parseWorkflowTemplateFileName)(input.path);
    if (parsed === null) {
        throw new Error(`Invalid workflow template path: ${input.path}`);
    }
    return {
        templatePath: input.path,
        fileName: input.path.split("/").at(-1) ?? input.path,
        filePath: input.path,
        system: (0, template_registry_1.isSystemWorkflowTemplatePath)(input.path),
        source: "repository",
        body: input.body,
        digest: input.digest,
        targets: input.targets,
        autoSelect: input.autoSelect,
        metadata: {
            description: input.description,
            requiredSkills: input.requiredSkills,
            requiredMcp: input.requiredMcp,
            targets: input.targets,
            autoSelect: input.autoSelect,
        },
    };
}
function buildWorkerWorkflowTemplateCatalog(input) {
    const existingTemplates = input.existingWorkflowTemplates
        .filter((template) => template.path !== input.replacedTemplatePath)
        .map((template) => buildExistingWorkerWorkflowTemplateRecord(template));
    const templates = [...existingTemplates, input.template];
    return {
        templates,
        templateByPath: new Map(templates.map((template) => [template.templatePath, template])),
    };
}
function formatWorkerTemplateStructureIssueMessage(diagnostic) {
    const details = [diagnostic.code, `line=${diagnostic.lineNumber}`];
    return `body must satisfy workflow template validation (${details.join(", ")}).`;
}
function startsWithWorkerTemplateFrontmatter(body) {
    const trimmed = body.trimStart();
    return trimmed.startsWith("---\n") || trimmed.startsWith("---\r\n");
}
function validateWorkerTemplateRequiredSkills(requiredSkills) {
    const issues = [];
    for (const [index, skillRef] of requiredSkills.entries()) {
        if (!(0, required_skills_1.isValidRequiredSkillRef)(skillRef)) {
            (0, validation_issues_1.addWorkerSemanticValidationIssue)(issues, {
                path: ["requires", "skills", index],
                message: "requires.skills entries must be available skill refs, such as browser-qa, codex:openai-docs, or claude:browser-qa.",
            });
        }
    }
    if (new Set(requiredSkills).size !== requiredSkills.length) {
        (0, validation_issues_1.addWorkerSemanticValidationIssue)(issues, {
            path: ["requires", "skills"],
            message: "requires.skills must not contain duplicate skill refs.",
        });
    }
    return issues;
}
function validateWorkerTemplateRequiredMcp(requiredMcp) {
    const issues = [];
    for (const [index, mcpRef] of requiredMcp.entries()) {
        if (!(0, required_mcp_1.isValidRequiredMcpRef)(mcpRef)) {
            (0, validation_issues_1.addWorkerSemanticValidationIssue)(issues, {
                path: ["requires", "mcp", index],
                message: "requires.mcp entries must be MCP refs, such as github, github/list_issues, codex:github, or claude:github/list_issues.",
            });
        }
    }
    if (new Set(requiredMcp).size !== requiredMcp.length) {
        (0, validation_issues_1.addWorkerSemanticValidationIssue)(issues, {
            path: ["requires", "mcp"],
            message: "requires.mcp must not contain duplicate MCP refs.",
        });
    }
    return issues;
}
function validateWorkerTemplateContentSemanticRules(input) {
    const issues = [];
    if (startsWithWorkerTemplateFrontmatter(input.body)) {
        (0, validation_issues_1.addWorkerSemanticValidationIssue)(issues, {
            path: ["body"],
            message: input.frontmatterMessage,
        });
    }
    (0, validation_issues_1.appendWorkerValidationIssues)(issues, validateWorkerTemplateRequiredSkills(input.requiredSkills));
    (0, validation_issues_1.appendWorkerValidationIssues)(issues, validateWorkerTemplateRequiredMcp(input.requiredMcp));
    (0, validation_issues_1.appendWorkerValidationIssues)(issues, input.validateBodyStructure());
    return issues;
}
function validateWorkerTemplateBodyStructure(input) {
    const template = buildWorkerWorkflowTemplateRecord({
        path: input.path,
        description: input.description,
        requiredSkills: [...input.requiredSkills],
        requiredMcp: [...input.requiredMcp],
        targets: [...input.targets],
        autoSelect: input.autoSelect,
        body: input.body,
        digest: input.digest,
    });
    const catalog = buildWorkerWorkflowTemplateCatalog({
        template,
        existingWorkflowTemplates: input.existingWorkflowTemplates,
        ...(input.replacedTemplatePath === undefined
            ? {}
            : { replacedTemplatePath: input.replacedTemplatePath }),
    });
    return [
        ...(0, validation_1.validateWorkflowTemplateStructure)(template),
        ...(0, validation_1.validateWorkflowTemplateTree)({
            catalog,
            rootTemplate: template,
            maxNestedWorkflowDepth: input.maxNestedWorkflowDepth ?? 5,
        }).diagnostics,
    ].map((diagnostic) => (0, validation_issues_1.createWorkerSemanticValidationIssue)({
        path: ["body"],
        message: formatWorkerTemplateStructureIssueMessage(diagnostic),
    }));
}
function buildExistingWorkerWorkflowTemplateRecord(template) {
    const parsed = (0, template_registry_1.parseWorkflowTemplateFileName)(template.path);
    if (parsed === null) {
        throw new Error(`Invalid workflow template path: ${template.path}`);
    }
    const targets = [...template.targets];
    return {
        templatePath: template.path,
        fileName: template.path.split("/").at(-1) ?? template.path,
        filePath: template.path,
        system: (0, template_registry_1.isSystemWorkflowTemplatePath)(template.path),
        source: "repository",
        body: template.body,
        digest: `${template.path}:existing`,
        targets,
        autoSelect: template.autoSelect,
        metadata: {
            description: template.description,
            requiredSkills: [...template.requiredSkills],
            requiredMcp: [...template.requiredMcp],
            targets,
            autoSelect: template.autoSelect,
        },
    };
}
