"use strict";
// src/cli/CommandFlowRunner.ts
// CLI wrapper around WorkflowParser + WorkflowEngine. Implements the
// `openlife flow {list,run,status,resume}` command surface.
//
// Discovery order for workflow YAMLs:
//   1. `.openlife/method/workflows/<id>.yaml` (project-local override)
//   2. `.catalog/workflows/<id>.yaml` (catalog override)
//   3. `<package>/dist-templates/workflows/<id>.yaml` (bundled defaults)
//
// State is persisted to `.openlife/workflows/<runId>.json` for resume.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.FLOW_ALIASES = void 0;
exports.workflowRoots = workflowRoots;
exports.listFlows = listFlows;
exports.resolveFlowId = resolveFlowId;
exports.findFlow = findFlow;
exports.dryRunFlow = dryRunFlow;
exports.renderDryRun = renderDryRun;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const WorkflowParser_1 = require("../orchestrator/workflow/WorkflowParser");
/** Resolve all workflow source directories in lookup-priority order. */
function workflowRoots(cwd = process.cwd()) {
    const roots = [];
    roots.push({ dir: path.join(cwd, '.openlife', 'method', 'workflows'), source: 'local' });
    roots.push({ dir: path.join(cwd, '.catalog', 'workflows'), source: 'catalog' });
    // Bundled: dist/cli/CommandFlowRunner.js → __dirname is dist/cli
    // package root is __dirname/../..
    const packageRoot = path.join(__dirname, '..', '..');
    roots.push({ dir: path.join(packageRoot, 'dist-templates', 'workflows'), source: 'bundled' });
    return roots;
}
/** List all available workflows across all roots (dedupes by id, first wins). */
function listFlows(cwd = process.cwd()) {
    const seen = new Map();
    for (const root of workflowRoots(cwd)) {
        if (!fs.existsSync(root.dir))
            continue;
        for (const f of fs.readdirSync(root.dir)) {
            if (!f.endsWith('.yaml') && !f.endsWith('.yml'))
                continue;
            const fp = path.join(root.dir, f);
            try {
                const parsed = (0, WorkflowParser_1.parseWorkflowFile)(fp);
                if (!parsed.workflow)
                    continue;
                const wf = parsed.workflow;
                if (seen.has(wf.id))
                    continue;
                seen.set(wf.id, {
                    id: wf.id,
                    name: wf.name,
                    type: wf.type,
                    description: wf.description || '',
                    steps: (wf.sequence || []).length,
                    source: root.source,
                    sourcePath: fp,
                });
            }
            catch { /* skip unparseable */ }
        }
    }
    return Array.from(seen.values()).sort((a, b) => a.id.localeCompare(b.id));
}
/**
 * Legacy workflow-id aliases → canonical id. Keeps old commands working after a
 * rename (e.g. `flow run brownfield-discovery` still resolves to brownfield-blueprint).
 */
exports.FLOW_ALIASES = {
    'brownfield-discovery': 'brownfield-blueprint',
};
/** Resolve a possibly-legacy workflow id to its canonical form. */
function resolveFlowId(id) {
    return exports.FLOW_ALIASES[id] || id;
}
/** Find a single workflow by id across all roots. Returns null if not found. */
function findFlow(id, cwd = process.cwd()) {
    const resolvedId = resolveFlowId(id);
    for (const root of workflowRoots(cwd)) {
        if (!fs.existsSync(root.dir))
            continue;
        for (const ext of ['.yaml', '.yml']) {
            const fp = path.join(root.dir, `${resolvedId}${ext}`);
            if (!fs.existsSync(fp))
                continue;
            const parsed = (0, WorkflowParser_1.parseWorkflowFile)(fp);
            if (parsed.workflow) {
                return { workflow: parsed.workflow, sourcePath: fp, source: root.source };
            }
        }
    }
    return null;
}
function dryRunFlow(id, cwd = process.cwd()) {
    const found = findFlow(id, cwd);
    if (!found)
        return null;
    const wf = found.workflow;
    const steps = (wf.sequence || []).map((s) => ({
        phase: 'phase' in s ? s.phase : undefined,
        name: 'name' in s ? s.name : undefined,
        id: 'id' in s ? s.id : undefined,
        agent: 'agent' in s ? s.agent : undefined,
        squad: 'squad' in s ? s.squad : undefined,
        action: 'action' in s ? s.action : undefined,
        task: 'task' in s ? s.task : undefined,
        optional: 'optional' in s ? s.optional : undefined,
        elicit: 'elicit' in s ? s.elicit : undefined,
    }));
    return {
        id: wf.id,
        name: wf.name,
        type: wf.type,
        steps,
    };
}
/**
 * Render a dry-run summary as human-readable lines suitable for terminal output.
 */
function renderDryRun(summary) {
    const lines = [];
    lines.push(`Workflow: ${summary.id} (${summary.type})`);
    lines.push(`Name: ${summary.name}`);
    lines.push(`Steps: ${summary.steps.length}`);
    lines.push('');
    for (const s of summary.steps) {
        if (s.phase !== undefined && s.name) {
            lines.push(`── Phase ${s.phase}: ${s.name}`);
            continue;
        }
        const tags = [];
        if (s.agent)
            tags.push(`agent=${s.agent}`);
        if (s.squad)
            tags.push(`squad=${s.squad}`);
        if (s.action)
            tags.push(`action=${s.action}`);
        if (s.task)
            tags.push(`task=${s.task}`);
        if (s.optional)
            tags.push('OPTIONAL');
        if (s.elicit)
            tags.push('ELICIT');
        lines.push(`   • ${s.id || '(unnamed step)'} — ${tags.join(' ') || '(no tags)'}`);
    }
    return lines;
}
