/**
 * OwlCoda Native TaskOutput Tool
 *
 * Retrieves output from a task by ID, optionally blocking until completion.
 *
 * Upstream parity notes:
 * - Upstream reads from disk-based task output, supports bash/agent task types
 * - Polls with configurable timeout, returns structured output
 * - Our version: reads from in-memory task store with optional polling
 */
import { getTask, getCurrentOrNextStep } from './task-store.js';
const STEP_ICON = {
    pending: '○',
    in_progress: '▶',
    completed: '✓',
    failed: '✗',
    blocked: '!',
    cancelled: '-',
};
function formatStepLine(step) {
    const icon = STEP_ICON[step.status] ?? '?';
    const label = `${icon} ${step.id} ${step.title} [${step.status}]`;
    return step.failureReason ? `${label} ${step.failureReason}` : label;
}
function formatNextStepSection(task) {
    const next = getCurrentOrNextStep(task.id);
    if (!next)
        return '';
    const lines = [`\nNext:`, `  ${next.id} ${next.title}`];
    if (next.expectedArtifacts.length > 0) {
        lines.push('  Expected artifacts:');
        for (const a of next.expectedArtifacts) {
            lines.push(`    - ${a.kind} ${a.origin} ${a.path}`);
        }
    }
    if (next.verification.length > 0) {
        lines.push('  Verification:');
        for (const v of next.verification) {
            if (v.kind === 'file_exists')
                lines.push(`    - file_exists ${v.path}`);
            else if (v.kind === 'file_contains')
                lines.push(`    - file_contains ${v.path} /${v.pattern}/`);
            else if (v.kind === 'artifact_count')
                lines.push(`    - artifact_count ${v.root} ${v.glob} min=${v.min}`);
            else if (v.kind === 'command')
                lines.push(`    - command ${v.command}`);
            else if (v.kind === 'none')
                lines.push(`    - none (${v.reason})`);
        }
    }
    return lines.join('\n');
}
function formatTaskOutput(task) {
    const lines = [
        `Task: ${task.id}`,
        `Subject: ${task.subject}`,
        `Status: ${task.status}`,
        `Description: ${task.description}`,
    ];
    if (task.activeForm)
        lines.push(`Active: ${task.activeForm}`);
    if (task.blocks.length > 0)
        lines.push(`Blocks: ${task.blocks.join(', ')}`);
    if (task.blockedBy.length > 0)
        lines.push(`Blocked by: ${task.blockedBy.join(', ')}`);
    // Structured plan board (Slice 1)
    if (task.steps) {
        if (task.deliverables && task.deliverables.length > 0) {
            lines.push('\nDeliverables:');
            for (const d of task.deliverables) {
                lines.push(`  - ${d.kind} ${d.origin} ${d.path}`);
            }
        }
        lines.push('\nSteps:');
        for (const step of task.steps) {
            lines.push('  ' + formatStepLine(step));
        }
        lines.push(formatNextStepSection(task));
        return lines.join('\n');
    }
    // Command-backed tasks: surface command, exit code, and captured I/O.
    // Pure-todo tasks (no command) keep the original output shape.
    if (task.command !== undefined) {
        lines.push(`Command: ${task.command}`);
        if (task.exitCode !== undefined)
            lines.push(`ExitCode: ${task.exitCode}`);
        if (task.error)
            lines.push(`Error: ${task.error}`);
        if (task.stdout && task.stdout.length > 0) {
            lines.push('--- stdout ---');
            lines.push(task.stdout.replace(/\n+$/, ''));
        }
        if (task.stderr && task.stderr.length > 0) {
            lines.push('--- stderr ---');
            lines.push(task.stderr.replace(/\n+$/, ''));
        }
    }
    return lines.join('\n');
}
function commandMetadata(task) {
    if (task.command === undefined)
        return {};
    return {
        command: task.command,
        stdout: task.stdout ?? '',
        stderr: task.stderr ?? '',
        exitCode: task.exitCode,
        ...(task.error ? { error: task.error } : {}),
    };
}
function buildTaskMeta(task) {
    const base = {
        task_id: task.id,
        status: task.status,
        description: task.description,
    };
    if (task.steps) {
        const nextStep = getCurrentOrNextStep(task.id);
        const completedCount = task.steps.filter(s => s.status === 'completed').length;
        base.stepCount = task.steps.length;
        base.completedSteps = completedCount;
        base.currentStepId = task.currentStepId ?? null;
        base.openStepCount = task.steps.filter(s => s.status === 'pending' || s.status === 'in_progress' || s.status === 'failed' || s.status === 'blocked').length;
        base.nextStep = nextStep ? {
            id: nextStep.id,
            title: nextStep.title,
            status: nextStep.status,
            expectedArtifacts: nextStep.expectedArtifacts,
            verification: nextStep.verification,
        } : null;
    }
    return base;
}
export function createTaskOutputTool() {
    return {
        name: 'TaskOutput',
        description: 'Read one task entry from the in-memory store, returning its current status snapshot. ' +
            'For structured task plans (created with steps), returns the execution board with step statuses ' +
            'and the next step to execute — block=true returns immediately for structured plans (no background producer). ' +
            'For command-backed tasks, returns captured stdout/stderr/exitCode. ' +
            'For pure-TODO tasks (no command), block=true only resolves if TaskUpdate changes status to completed/cancelled. ' +
            'Metadata includes nextStep with expected artifacts and verification for structured plans.',
        maturity: 'beta',
        async execute(input) {
            const { task_id, block = true, timeout = 30000 } = input;
            if (!task_id) {
                return { output: 'Error: task_id is required.', isError: true };
            }
            const task = getTask(task_id);
            if (!task) {
                return { output: `Task "${task_id}" not found.`, isError: true };
            }
            // Structured plan: block=true returns immediately — there is no background producer
            const isStructuredPlan = task.steps !== undefined;
            const isTerminal = task.status === 'completed' || task.status === 'cancelled';
            if (isTerminal || !block || isStructuredPlan) {
                return {
                    output: formatTaskOutput(task),
                    isError: false,
                    metadata: {
                        retrieval_status: 'success',
                        task: {
                            ...buildTaskMeta(task),
                            ...(!isStructuredPlan ? commandMetadata(task) : {}),
                        },
                    },
                };
            }
            // Block: poll until terminal or timeout (command-backed / pure-TODO tasks only)
            const deadline = Date.now() + timeout;
            const pollInterval = 500;
            while (Date.now() < deadline) {
                await new Promise(r => setTimeout(r, pollInterval));
                const current = getTask(task_id);
                if (!current) {
                    return { output: `Task "${task_id}" was deleted while waiting.`, isError: true };
                }
                if (current.status === 'completed' || current.status === 'cancelled') {
                    return {
                        output: formatTaskOutput(current),
                        isError: false,
                        metadata: {
                            retrieval_status: 'success',
                            task: {
                                ...buildTaskMeta(current),
                                ...commandMetadata(current),
                            },
                        },
                    };
                }
            }
            // Timeout — return current state
            const final = getTask(task_id);
            return {
                output: `Timeout waiting for task ${task_id} (${timeout}ms). Current status: ${final?.status ?? 'unknown'}`,
                isError: false,
                metadata: {
                    retrieval_status: 'timeout',
                    task: final ? buildTaskMeta(final) : null,
                },
            };
        },
    };
}
//# sourceMappingURL=task-output.js.map