// ── 工具注册中间件 ──
// 封装安全的工具注册边界: 授权、状态预检、
// 计划门控、指令合同门控、设计产物门控、生命周期知识门控、
// 合同校验和错误处理。
//
// 从 tools.ts 第 1096-1658 行提取。
import path from "node:path";
import { promises as fsp } from "node:fs";
import { debug } from "../../engine/core/logger.js";
import { ENV } from "../../engine/core/env.js";
import { findToolInvocationContractByName, createToolTrace, validateToolInvocation, hasWriteSideEffect, } from "../../engine/contracts/tool_invocation_contract_registry.js";
import { TOOL_DIAGNOSTIC_CODES } from "../../engine/audit/diagnostic_registry.js";
import { lazyAnchor } from "./lazy_loaders.js";
import { checkWriteToolPlanGate, checkInstructionContractGate, checkDesignArtifactWriteGate, } from "./gate_checks.js";
import { errorMessage } from "../../engine/core/helpers.js";
// ── 工厂 ──
export function createToolRegistrar(ctx) {
    const { server, config, taskContext, projectPath } = ctx;
    // ── 辅助: 计算有效 category ──
    /** 计算 sf_status cancel 的动态 category */
    function computeEffectiveCategory(toolName, args, contract) {
        if (toolName === "sf_status" && (args.action === "cancel" || args.action === "archive_stale" || args.job_action === "job_cancel")) {
            return "normal_controlled";
        }
        return contract.category;
    }
    // ── 辅助: 计算有效副作用 ──
    /** 计算 sf_status cancel 的动态 side_effects */
    function computeEffectiveSideEffects(toolName, args, contract) {
        if (toolName === "sf_status" && (args.action === "cancel" || args.action === "archive_stale" || args.job_action === "job_cancel")) {
            return ["task_context_write"];
        }
        return contract.side_effects;
    }
    // ── 状态预检 ──
    /** 状态预检: 在合同守卫之前验证任务状态 */
    const STATE_PRECHECKS = {
        sf_accept: ["executing", "verifying", "retrying"],
        sf_verify: ["executing", "retrying"],
        sf_record_verification_execution: ["verifying", "executing"],
        sf_learn: ["verifying", "executing"],
        sf_expand: ["classifying", "expanding", "clarifying"],
    };
    const STATE_ERROR_LABELS = {
        sf_accept: "不可验收",
        sf_verify: "不可验证",
        sf_record_verification_execution: "不可录入验证结果",
        sf_learn: "不可学习",
        sf_expand: "不可膨胀",
    };
    // ── 授权模型 ──
    /** 授权模型: explicit > dynamic write gate > destructive gate > workflow gate > category default */
    function checkAuth(toolName, args, contract, tCtx, effectiveCategory) {
        // 1. 显式确认
        // 安全修复: authorization_token 在配置了 SOLOFORGE_AUTH_TOKEN 时必须精确匹配
        if (args.confirm === true || args.authorized === true) {
            return { required: true, granted: true, reason: "explicit confirmation" };
        }
        if (args.authorization_token) {
            const expectedToken = process.env[ENV.AUTH_TOKEN];
            if (expectedToken) {
                // 配置了 token 验证: 必须精确匹配
                if (args.authorization_token !== expectedToken) {
                    return { required: true, granted: false, reason: "authorization_token 不匹配" };
                }
            }
            // 未配置 AUTH_TOKEN 时保持旧行为（truthy 即通过）
            return { required: true, granted: true, reason: "explicit confirmation" };
        }
        // 1b. sf_status 的写入型动作必须显式确认，即便普通查询本身允许自动维护状态。
        if (toolName === "sf_status" && (args.action === "cancel" || args.action === "archive_stale" || args.job_action === "job_cancel")) {
            return { required: true, granted: false, reason: "dynamic write upgrade requires explicit confirmation" };
        }
        // 2. 动态写入升级: cancel/job_cancel 从 read_only 变为 write → 必须确认
        if (effectiveCategory && effectiveCategory !== contract.category && effectiveCategory !== "read_only_bypass") {
            return { required: true, granted: false, reason: "dynamic write upgrade requires explicit confirmation" };
        }
        // 3. 破坏性副作用始终需要显式确认
        const destructive = ["git_commit", "git_push", "pr_create", "external_write"];
        if (contract.side_effects.some((e) => destructive.includes(e))) {
            return { required: true, granted: false, reason: "destructive side effects require explicit confirmation" };
        }
        // 4. 独立严格工具（无 workflow 要求，无 task context）→ 由 handler 自行检查
        if (contract.category === "strict_controlled" && !tCtx && !contract.requires_workflow) {
            if (contract.requires_authorization) {
                return { required: true, granted: false, reason: "standalone strict tool requires explicit confirmation" };
            }
            return { required: false, granted: true, reason: "standalone strict tool" };
        }
        // 5. strict_controlled 的 workflow 合同门控
        if (contract.category === "strict_controlled" && tCtx?.last_tool_trace) {
            const allowed = tCtx.last_tool_trace.next_allowed_tools ?? [];
            if (allowed.includes(toolName)) {
                return { required: true, granted: true, reason: "workflow contract gate" };
            }
        }
        // 5b. 基于状态的回退: 严格工具且任务处于有效状态但无 tool_trace
        if (contract.category === "strict_controlled" && tCtx && !tCtx.last_tool_trace && contract.requires_workflow) {
            const validStates = STATE_PRECHECKS[toolName];
            if (validStates && validStates.includes(tCtx.status)) {
                return { required: true, granted: true, reason: "task in valid state for tool" };
            }
        }
        // 5c. 非严格工具: 自动授权，除非 requires_authorization
        if (contract.category === "read_only_bypass" || contract.category === "normal_controlled") {
            if (contract.requires_authorization) {
                return { required: true, granted: false, reason: "tool requires explicit authorization" };
            }
            return { required: false, granted: true, reason: "non-strict category" };
        }
        return { required: true, granted: false, reason: "no authorization source" };
    }
    // ── 安全工具注册 ──
    function registerSafeTool(name, desc, schema, handler) {
        // @ts-expect-error -- MCP SDK 桥接点: schema 参数类型不兼容 Record<string, ZodTypeAny>
        server.tool(name, desc, schema, async (args) => {
            const invocationId = `inv-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
            const taskId = typeof args.task_id === "string" ? args.task_id : undefined;
            const contract = findToolInvocationContractByName(name);
            // 无合同 → hard fail
            if (!contract) {
                return {
                    content: [{ type: "text", text: JSON.stringify({ error: `工具 ${name} 未注册契约` }) }],
                    isError: true,
                };
            }
            const effectiveCategory = computeEffectiveCategory(name, args, contract);
            const effectiveSideEffects = computeEffectiveSideEffects(name, args, contract);
            // 加载 TaskContext
            let tCtx = null;
            if (taskId) {
                tCtx = await taskContext.load(taskId);
            }
            // 状态预检: 在合同守卫之前验证任务状态
            if (taskId && STATE_PRECHECKS[name] && tCtx) {
                const validStates = STATE_PRECHECKS[name];
                if (!validStates.includes(tCtx.status)) {
                    const label = STATE_ERROR_LABELS[name] ?? "状态不正确";
                    return {
                        content: [{ type: "text", text: JSON.stringify({
                                    error: `任务状态 ${tCtx.status} ${label}，需要 ${validStates.join(" 或 ")}`,
                                    status: tCtx.status,
                                }) }],
                        isError: true,
                    };
                }
            }
            // 严格受控但缺少 task_id
            const isStandaloneStrict = !contract.requires_workflow;
            if (contract.category === "strict_controlled" && !taskId && !isStandaloneStrict) {
                return {
                    content: [{ type: "text", text: JSON.stringify({ error: `strict controlled 工具 ${name} 需要 task_id` }) }],
                    isError: true,
                };
            }
            // 授权检查
            const authorization = checkAuth(name, args, contract, tCtx ?? undefined, effectiveCategory);
            // 授权拒绝 → 仅对网关级拒绝执行 hard fail
            // （动态写入升级、破坏性操作、无授权源的 strict_controlled）
            // Handler 级授权（如 sf_capability_update confirm）由 handler 自行处理
            const gatewayDenial = !authorization.granted &&
                authorization.reason !== "tool requires explicit authorization";
            if (gatewayDenial) {
                const blockedTrace = createToolTrace({
                    tool_name: name, invocation_id: invocationId, task_id: taskId,
                    actual_side_effects: effectiveSideEffects,
                    next_allowed_tools: contract.default_next_tools,
                    forbidden_tools: contract.forbidden_next_tools,
                    authorization, bypass: undefined,
                });
                const authViolation = {
                    invocation_id: invocationId, tool_name: name,
                    violation_type: "missing_authorization", severity: "hard_fail",
                    reason: authorization.reason ?? "authorization denied",
                    recovery: "提供 confirm=true / authorized=true / authorization_token",
                };
                if (taskId && tCtx) {
                    await taskContext.setToolTrace(taskId, blockedTrace, [authViolation]);
                }
                return {
                    content: [{ type: "text", text: JSON.stringify({
                                error: authViolation.reason, violation: authViolation,
                                tool_trace: blockedTrace,
                                next_allowed_tools: contract.default_next_tools,
                                forbidden_tools: contract.forbidden_next_tools,
                            }) }],
                    isError: true,
                };
            }
            // read_only_bypass 的旁路处理
            const bypass = effectiveCategory === "read_only_bypass"
                ? { allowed: true, reason: "read_only" } : undefined;
            // 计划前置门: 在合同验证之前检查 — 写工具必须有 plan_proposal_gate
            // sf_classify 创建任务、sf_expand 创建 plan_proposal_gate — 两者豁免
            const hasWriteEffect = hasWriteSideEffect(effectiveSideEffects);
            const planGateExempt = name === "sf_classify" || name === "sf_expand";
            if (hasWriteEffect && taskId && !planGateExempt) {
                const pgResult = checkWriteToolPlanGate({ ctx: tCtx, toolName: name, sideEffects: effectiveSideEffects });
                if (!pgResult.allowed) {
                    const planViolation = {
                        invocation_id: invocationId, tool_name: name,
                        violation_type: "guard_blocked", severity: "hard_fail",
                        reason: pgResult.reason ?? "执行前缺少 Plan Proposal Gate",
                        recovery: "先调用 sf_classify → sf_expand → 设置 plan_proposal_gate 后再执行此工具",
                    };
                    const blockedTrace = createToolTrace({
                        tool_name: name, invocation_id: invocationId, task_id: taskId,
                        actual_side_effects: effectiveSideEffects,
                        next_allowed_tools: contract.default_next_tools,
                        forbidden_tools: contract.forbidden_next_tools,
                        authorization, bypass,
                    });
                    await taskContext.setToolTrace(taskId, blockedTrace, [planViolation]);
                    return {
                        content: [{ type: "text", text: JSON.stringify({
                                    error: planViolation.reason,
                                    violation: planViolation,
                                    diagnostic_code: pgResult.diagnostic_code ?? TOOL_DIAGNOSTIC_CODES.planGate,
                                    recovery: planViolation.recovery,
                                }) }],
                        isError: true,
                    };
                }
                const planGateCheck = taskContext.checkPlanGateBeforeWrite(tCtx);
                if (!planGateCheck.allowed) {
                    const planViolation = {
                        invocation_id: invocationId, tool_name: name,
                        violation_type: "guard_blocked", severity: "hard_fail",
                        reason: planGateCheck.reason_zh,
                        recovery: "请先通过 PlanProposalFirstGate 生成并确认执行计划",
                    };
                    const blockedTrace = createToolTrace({
                        tool_name: name, invocation_id: invocationId, task_id: taskId,
                        actual_side_effects: effectiveSideEffects,
                        next_allowed_tools: contract.default_next_tools,
                        forbidden_tools: contract.forbidden_next_tools,
                        authorization, bypass,
                    });
                    await taskContext.setToolTrace(taskId, blockedTrace, [planViolation]);
                    return {
                        content: [{ type: "text", text: JSON.stringify({
                                    error: planViolation.reason,
                                    violation: planViolation,
                                    diagnostic_code: TOOL_DIAGNOSTIC_CODES.planGate,
                                    recovery: planViolation.recovery,
                                }) }],
                        isError: true,
                    };
                }
            }
            // 施工指令契约门: 写操作前检查 instruction_contract 状态
            if (hasWriteEffect && taskId) {
                const instrResult = await checkInstructionContractGate({ ctx: tCtx, toolName: name, sideEffects: effectiveSideEffects, task_id: taskId, taskContextMgr: taskContext });
                if (!instrResult.allowed) {
                    const instrViolation = {
                        invocation_id: invocationId, tool_name: name,
                        violation_type: "guard_blocked", severity: "hard_fail",
                        reason: instrResult.reason ?? "施工指令未就绪",
                        recovery: "请先完善施工指令（目标、范围、非目标、落点、验收标准、禁止绕过项）",
                    };
                    const instrTrace = createToolTrace({
                        tool_name: name, invocation_id: invocationId, task_id: taskId,
                        actual_side_effects: effectiveSideEffects,
                        next_allowed_tools: contract.default_next_tools,
                        forbidden_tools: contract.forbidden_next_tools,
                        authorization, bypass,
                    });
                    await taskContext.setToolTrace(taskId, instrTrace, [instrViolation]);
                    return {
                        content: [{ type: "text", text: JSON.stringify({
                                    error: instrViolation.reason,
                                    violation: instrViolation,
                                    diagnostic_code: instrResult.diagnostic_code ?? TOOL_DIAGNOSTIC_CODES.instructionContract,
                                    recovery: instrViolation.recovery,
                                }) }],
                        isError: true,
                    };
                }
            }
            // 问题六十二: MCP 写入路径同样必须消费设计产物包状态，不能绕开 CLI hook。
            if (hasWriteEffect && taskId) {
                const designWriteGate = checkDesignArtifactWriteGate({ ctx: tCtx, toolName: name, sideEffects: effectiveSideEffects });
                if (!designWriteGate.allowed) {
                    const designViolation = {
                        invocation_id: invocationId, tool_name: name,
                        violation_type: "guard_blocked", severity: "hard_fail",
                        reason: designWriteGate.reason ?? "设计产物包未达到实现就绪状态",
                        recovery: "仅可继续补充设计资产并执行 sf_verify 真实复验；通过前不得写入业务实现",
                    };
                    const designTrace = createToolTrace({
                        tool_name: name, invocation_id: invocationId, task_id: taskId,
                        actual_side_effects: effectiveSideEffects,
                        next_allowed_tools: contract.default_next_tools,
                        forbidden_tools: contract.forbidden_next_tools,
                        authorization, bypass,
                    });
                    await taskContext.setToolTrace(taskId, designTrace, [designViolation]);
                    return {
                        content: [{ type: "text", text: JSON.stringify({
                                    error: designViolation.reason,
                                    violation: designViolation,
                                    diagnostic_code: designWriteGate.diagnostic_code,
                                    recovery: designViolation.recovery,
                                }) }],
                        isError: true,
                    };
                }
            }
            // 用户项目知识门禁: review/verify/deliver 不能绕过不可消费的项目 hard rule。
            if (["sf_review", "sf_verify", "sf_deliver"].includes(name)) {
                const { evaluateLifecycleKnowledgeDecision } = await import("../../engine/contracts/lifecycle_knowledge_contract.js");
                const lifecycleStage = name === "sf_review" ? "implementation" : name === "sf_verify" ? "testing" : "delivery";
                const lifecycleDecision = evaluateLifecycleKnowledgeDecision({
                    projectPath,
                    consumer: name,
                    intent: tCtx?.intent ?? name,
                    route: name === "sf_review" ? "review" : name === "sf_verify" ? "verification" : "delivery",
                    lifecycle_stage: lifecycleStage,
                    changed_files: Array.isArray(args.changed_files) ? args.changed_files : tCtx?.execution?.changed_files ?? [],
                    verified_files: Array.isArray(args.changed_files) ? args.changed_files : tCtx?.execution?.changed_files ?? [],
                    traceability_ids: [
                        ...(tCtx?.traceability_binding?.requirement_ids ?? []),
                        ...(tCtx?.traceability_binding?.prototype_ids ?? []),
                        ...(tCtx?.traceability_binding?.architecture_ids ?? []),
                        ...(tCtx?.traceability_binding?.detail_design_ids ?? []),
                        ...(tCtx?.traceability_binding?.phase_ids ?? []),
                        ...(tCtx?.traceability_binding?.slice_ids ?? []),
                        ...(tCtx?.traceability_binding?.acceptance_ids ?? []),
                    ],
                    config,
                    task_id: taskId,
                    require_design_audit: false,
                    enforce_control_plane: name !== "sf_review",
                    generation_traces: [
                        ...(tCtx?.classification ? [{ tool_name: "sf_classify", task_id: taskId, status: "passed", evidence_kind: "result" }] : []),
                        ...(tCtx?.expansion ? [{ tool_name: "sf_expand", task_id: taskId, status: "passed", evidence_kind: "result" }] : []),
                        ...(name === "sf_verify" ? [{ tool_name: "sf_verify", task_id: taskId, status: "blocked", evidence_kind: "plan" }] : []),
                    ],
                    selection_limit: 8,
                });
                if (lifecycleDecision.hard_fail_count > 0) {
                    const hardFindings = lifecycleDecision.findings
                        .filter((finding) => finding.severity === "hard_fail")
                        .map((finding) => `[${finding.code}] ${finding.message_zh}`);
                    const pkViolation = {
                        invocation_id: invocationId,
                        tool_name: name,
                        violation_type: "guard_blocked",
                        severity: "hard_fail",
                        reason: lifecycleDecision.decision_summary_zh,
                        recovery: lifecycleDecision.recovery_commands.join("；") || "运行 soloforge next 查看统一生命周期知识合同阻断项",
                    };
                    const pkTrace = createToolTrace({
                        tool_name: name, invocation_id: invocationId, task_id: taskId,
                        actual_side_effects: effectiveSideEffects,
                        next_allowed_tools: ["sf_expand", "sf_status"],
                        forbidden_tools: ["sf_review", "sf_verify", "sf_deliver"],
                        authorization, bypass,
                    });
                    if (taskId && tCtx)
                        await taskContext.setToolTrace(taskId, pkTrace, [pkViolation]);
                    return {
                        content: [{ type: "text", text: JSON.stringify({
                                    error: pkViolation.reason,
                                    violation: pkViolation,
                                    diagnostic_code: TOOL_DIAGNOSTIC_CODES.projectKnowledgeBlocked,
                                    findings: hardFindings,
                                    lifecycle_knowledge_decision: {
                                        contract_id: lifecycleDecision.contract_id,
                                        lifecycle_stage: lifecycleDecision.lifecycle_stage,
                                        authoritative_paths: lifecycleDecision.authoritative_paths,
                                        recovery_commands: lifecycleDecision.recovery_commands,
                                    },
                                    recovery: pkViolation.recovery,
                                }) }],
                        isError: true,
                    };
                }
            }
            // 合同验证
            const lastTrace = tCtx?.last_tool_trace;
            // 为动态工具构建有效的合同覆盖（如 sf_status cancel）
            let contractOverride;
            if (effectiveCategory !== contract.category || effectiveSideEffects !== contract.side_effects) {
                contractOverride = { ...contract, category: effectiveCategory, side_effects: effectiveSideEffects };
            }
            // Workflow ID: 仅来自真实的 expansion trace
            const explicitWorkflowId = tCtx?.expansion?.workflow_trace?.workflow_id;
            const violations = validateToolInvocation({
                tool_name: name,
                current_next_allowed: lastTrace?.next_allowed_tools ?? [],
                current_forbidden: lastTrace?.forbidden_tools ?? [],
                authorization,
                bypass,
                actual_side_effects: effectiveSideEffects,
                workflow_id: explicitWorkflowId,
                _contractOverride: contractOverride,
            });
            // 基于状态的回退: 将 contract_state_mismatch 从 hard_fail 降级为 require_human
            if (authorization.reason === "task in valid state for tool") {
                for (const v of violations) {
                    if (v.violation_type === "contract_state_mismatch" && v.severity === "hard_fail") {
                        v.severity = "require_human";
                        v.reason += " (state-based fallback: no real workflow_id)";
                    }
                }
            }
            // Hard-fail 违规 → 阻止
            const hardFail = violations.find(v => v.severity === "hard_fail");
            if (hardFail) {
                const blockedTrace = createToolTrace({
                    tool_name: name, invocation_id: invocationId, task_id: taskId,
                    actual_side_effects: effectiveSideEffects,
                    next_allowed_tools: contract.default_next_tools,
                    forbidden_tools: contract.forbidden_next_tools,
                    authorization, bypass,
                });
                if (taskId && tCtx) {
                    await taskContext.setToolTrace(taskId, blockedTrace, violations);
                }
                return {
                    content: [{ type: "text", text: JSON.stringify({
                                error: hardFail.reason, violation: hardFail,
                                tool_trace: blockedTrace,
                                next_allowed_tools: contract.default_next_tools,
                                forbidden_tools: contract.forbidden_next_tools,
                            }) }],
                    isError: true,
                };
            }
            // 执行 handler
            try {
                const raw = await handler(args);
                // 如果 handler 直接返回 { content } 则透传，但补充 trace 写入
                if (raw && typeof raw === "object" && "content" in raw && Array.isArray(raw.content)) {
                    // [ENG-6] content 格式路径也需要写入 trace
                    if (taskId) {
                        const passthroughTrace = createToolTrace({
                            tool_name: name, invocation_id: invocationId, task_id: taskId,
                            workflow_id: tCtx?.expansion?.workflow_trace?.workflow_id,
                            actual_side_effects: effectiveSideEffects,
                            next_allowed_tools: contract.default_next_tools,
                            forbidden_tools: contract.forbidden_next_tools,
                            authorization, bypass,
                        });
                        try {
                            await taskContext.setToolTrace(taskId, passthroughTrace, violations.length > 0 ? violations : undefined);
                        }
                        catch { /* best effort */ }
                    }
                    return raw;
                }
                // 从 { result } 模式中提取数据
                const rawRec = raw;
                const data = rawRec?.result !== undefined ? rawRec.result : rawRec;
                const hasError = !!(data && typeof data === "object" && "error" in data);
                const dataRec = data;
                const recoveryNextTools = hasError && Array.isArray(dataRec.recovery_next_tools)
                    ? dataRec.recovery_next_tools
                    : contract.default_next_tools;
                const recoveryForbiddenTools = hasError && Array.isArray(dataRec.recovery_forbidden_tools)
                    ? dataRec.recovery_forbidden_tools
                    : contract.forbidden_next_tools;
                // 构建 trace；失败处理器可显式开放修复重验路径
                const trace = createToolTrace({
                    tool_name: name, invocation_id: invocationId, task_id: taskId,
                    workflow_id: tCtx?.expansion?.workflow_trace?.workflow_id,
                    actual_side_effects: effectiveSideEffects,
                    next_allowed_tools: recoveryNextTools,
                    forbidden_tools: recoveryForbiddenTools,
                    authorization, bypass,
                });
                // 将 trace 写入 TaskContext
                if (taskId) {
                    await taskContext.setToolTrace(taskId, trace, violations.length > 0 ? violations : undefined);
                }
                // 用 trace + next/forbidden 装饰响应
                const response = {
                    ...data,
                    tool_trace: trace,
                    next_allowed_tools: recoveryNextTools,
                    forbidden_tools: recoveryForbiddenTools,
                };
                // 基于状态的回退: 在响应中暴露降级 workflow
                if (authorization.reason === "task in valid state for tool") {
                    response.degraded_workflow = true;
                    response.workflow_source = "state-based-fallback";
                }
                return {
                    content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
                    isError: hasError ? true : undefined,
                };
            }
            catch (err) {
                const errorNextTools = name === "sf_expand"
                    ? ["sf_expand", "sf_status", "sf_debug", "sf_governance_report"]
                    : contract.default_next_tools;
                const errorForbiddenTools = name === "sf_expand"
                    ? ["sf_verify", "sf_review", "sf_deliver", "sf_scaffold"]
                    : contract.forbidden_next_tools;
                if (name === "sf_expand" && taskId) {
                    // [ENG-7] 记录失败信息到 trace 再标记 failed，不跳过失败分析流程
                    try {
                        await taskContext.updateStatus(taskId, "failed");
                    }
                    catch { /* best effort */ }
                }
                const errorTrace = createToolTrace({
                    tool_name: name, invocation_id: invocationId, task_id: taskId,
                    actual_side_effects: effectiveSideEffects,
                    next_allowed_tools: errorNextTools,
                    forbidden_tools: errorForbiddenTools,
                    authorization, bypass,
                });
                if (taskId) {
                    try {
                        await taskContext.setToolTrace(taskId, errorTrace);
                    }
                    catch { /* best effort */ }
                }
                return {
                    content: [{ type: "text", text: JSON.stringify({
                                error: errorMessage(err),
                                tool_trace: errorTrace,
                                next_allowed_tools: errorNextTools,
                                forbidden_tools: errorForbiddenTools,
                            }) }],
                    isError: true,
                };
            }
        });
    }
    // ── 加载认知锚点上下文 ──
    // 加载认知锚点上下文 — 必须提供相关性参数，禁止全量加载
    async function loadRelevantAnchors(query) {
        debug("工具注册", "加载认知锚点");
        return _loadRelevantAnchorsInner(query);
    }
    async function _loadRelevantAnchorsInner(query) {
        const stateDir = taskContext.getStateDir();
        const mapPath = path.join(stateDir, "cognitive.map.json");
        const mapData = (await lazyAnchor()).readMapJson(mapPath);
        if (!mapData || mapData.anchors.length === 0)
            return undefined;
        const existingFiles = new Set();
        try {
            for (const anchor of mapData.anchors) {
                for (const ref of anchor.source_refs) {
                    if (ref.type === "file" && await fsp.access(path.join(projectPath, ref.ref)).then(() => true, () => false)) {
                        existingFiles.add(ref.ref);
                    }
                }
            }
        }
        catch { /* ignore */ }
        const checked = (await lazyAnchor()).checkAnchorStaleness(mapData.anchors, existingFiles);
        // 必须有 module 或 file_paths，否则不返回任何锚点（禁止全量加载）
        if (!query.module && (!query.file_paths || query.file_paths.length === 0))
            return undefined;
        // 收集与任意提供的 file_paths 或 module 匹配的锚点
        const seen = new Set();
        const relevant = [];
        if (query.module) {
            for (const a of (await lazyAnchor()).filterRelevantAnchors(checked, { module: query.module })) {
                if (!seen.has(a.anchor_id)) {
                    seen.add(a.anchor_id);
                    relevant.push(a);
                }
            }
        }
        if (query.file_paths) {
            for (const fp of query.file_paths) {
                for (const a of (await lazyAnchor()).filterRelevantAnchors(checked, { file_path: fp })) {
                    if (!seen.has(a.anchor_id)) {
                        seen.add(a.anchor_id);
                        relevant.push(a);
                    }
                }
            }
        }
        if (relevant.length === 0)
            return undefined;
        return relevant.map((a) => ({
            anchor_id: a.anchor_id,
            module: a.module,
            summary: a.core_contracts.slice(0, 3).join("; "),
            stale_anchor: a.stale_anchor,
        }));
    }
    return { registerSafeTool, loadRelevantAnchors };
}
//# sourceMappingURL=middleware.js.map