// tools/response-helpers.ts — Reusable response formatting for MCP tool handlers
import { t, ti } from '../i18n/index.js';
import { compactJson } from './output-formatter.js';
import { getDirectiveText, getHumanSummaryPrefix } from '../engine/host-rules-templates/index.js';
/**
 * Format a success response with optional next steps.
 * Output: ✅ **{title}**\n\n{body}\n\n🚀 **Next Steps**\n1. ...\n2. ...
 */
export function formatSuccess(title, body, nextSteps) {
    const header = `✅ **${title}**`;
    const parts = [header, '', body];
    if (nextSteps && nextSteps.length > 0) {
        parts.push('', t('tools.response.nextSteps'));
        nextSteps.forEach((step, i) => parts.push(`${String(i + 1)}. ${step}`));
    }
    return parts.join('\n');
}
/**
 * Format a warning with blockquote and optional suggestions.
 * Output: ⚠️ **{title}**\n> {body}\n\n💡 **Suggestions**\n- ...
 */
export function formatWarning(title, body, suggestions) {
    const header = `⚠️ **${title}**`;
    const quotedBody = body
        .split('\n')
        .map((line) => `> ${line}`)
        .join('\n');
    const parts = [header, quotedBody];
    if (suggestions && suggestions.length > 0) {
        parts.push('', t('tools.response.suggestions'));
        suggestions.forEach((s) => parts.push(`- ${s}`));
    }
    return parts.join('\n');
}
/**
 * Format an error with fix instructions.
 * Output: ❌ **Error:** {message}\n💡 **How to fix:** {fix}
 */
export function formatError(message, fix) {
    const errorLine = ti('tools.response.error', { message });
    if (!fix) {
        return errorLine;
    }
    return `${errorLine}\n${ti('tools.response.howToFix', { fix })}`;
}
/**
 * Append a next-steps section to existing text.
 */
export function addNextSteps(text, steps) {
    if (steps.length === 0) {
        return text;
    }
    const section = [t('tools.response.nextSteps')];
    steps.forEach((step, i) => section.push(`${String(i + 1)}. ${step}`));
    return `${text}\n\n${section.join('\n')}`;
}
/**
 * Wrap a JSON-serializable value into a success ToolResult.
 * The value is compact-printed as JSON text content (via output-formatter).
 */
export function jsonResult(data) {
    return { content: [{ type: 'text', text: compactJson(data) }] };
}
/**
 * Wrap a plain text message into a ToolResult.
 */
export function textResult(message) {
    return { content: [{ type: 'text', text: message }] };
}
/**
 * Wrap an error message into a ToolResult with isError: true.
 * The message is returned as plain text (not JSON-wrapped).
 */
export function errText(message) {
    return { content: [{ type: 'text', text: message }], isError: true };
}
/**
 * Wrap a JSON-serializable error payload into a ToolResult with isError: true.
 */
export function errJson(data) {
    return {
        content: [{ type: 'text', text: compactJson(data) }],
        isError: true,
    };
}
/**
 * SPEC-695 + SPEC-708: Build a ToolResult for interactive clarification with mandatory
 * humanSummary and host-aware directive text. Guarantees that every interactiveQuestions[]
 * response has an explicit relay instruction matching the connected host's native UI
 * (AskUserQuestion in Claude Code, Composer follow-up in Cursor, native prompt in Codex/Gemini).
 */
export function interactiveResult(questions, message, hostHint = 'claude-code') {
    const first = questions[0]?.question ?? 'Please answer the questions below.';
    const humanSummary = `${getHumanSummaryPrefix(hostHint)}: ${first}`;
    return {
        content: [
            {
                type: 'text',
                text: getDirectiveText(hostHint),
            },
        ],
        structuredContent: {
            needsClarification: true,
            message,
            interactiveQuestions: questions,
            humanSummary,
            hostHint,
        },
    };
}
/**
 * SPEC-729: Build the standard 3-option AskUserQuestion payload for escalation decisions.
 *
 * Called when `withEscalation` returns an escalation sentinel and the caller needs to
 * surface the decision to the human operator via interactiveQuestions.
 *
 * @param role       - The escalated role (reviewer | validator | releaser).
 * @param lastReason - The reason from the last failed attempt.
 * @returns An InteractiveQuestion[] ready for use with `interactiveResult`.
 */
export function escalateDecisionPrompt(role, lastReason) {
    const roleLabel = role.charAt(0).toUpperCase() + role.slice(1);
    return [
        {
            question: `The ${roleLabel} has exhausted its retry budget. Last failure: "${lastReason}". How would you like to proceed?`,
            header: `${roleLabel} Fail`,
            options: [
                {
                    label: 'retry',
                    description: `Force another ${roleLabel} attempt beyond the normal budget (use when you believe the failure was transient).`,
                },
                {
                    label: 'abort (Recommended)',
                    description: `Cancel this operation and leave the spec in its current state. Safe option — no spec transitions occur.`,
                },
                {
                    label: 'manual-override',
                    description: `Manually advance the spec despite the ${roleLabel} failure. Requires a reason ≥ 30 characters and is audit-logged.`,
                },
            ],
            multiSelect: false,
        },
    ];
}
/**
 * Wrap text into a CallToolResult format.
 */
export function toolResult(text, structured, isError = false) {
    const result = {
        content: [{ type: 'text', text }],
    };
    if (isError) {
        result.isError = true;
    }
    if (structured) {
        result.structuredContent = structured;
    }
    return result;
}
//# sourceMappingURL=response-helpers.js.map