// Hatchway CLI - Built with Rollup
import { mkdir, writeFile } from 'node:fs/promises';
import { existsSync, rmSync, realpathSync } from 'node:fs';
import { join, resolve } from 'node:path';
import { randomBytes } from 'node:crypto';
import { j as jsxRuntimeExports, B as Box, r as reactExports, T as Text, s as symbols, c as colors, l as layout, a as useStdout, u as useInput, b as render } from './theme-NAQBkisB.js';
import 'chalk';
import 'node:stream';
import 'node:process';
import 'node:events';
import { u as useApp } from './use-app-Ct3w2jLI.js';
import { g as getVersionInfo, B as Banner } from './Banner-DL1Fpz_g.js';
import 'node:http';
import 'node:url';
import 'node:os';
import 'node:child_process';
import { c as configManager } from './config-manager-DST6RbP8.js';
import { i as isInsideMonorepo } from './repo-detector-36VydrlB.js';
import { isPnpmInstalled, cloneRepository, installDependencies, buildAgentCore } from './repo-cloner-UY3L2X7h.js';
import { p as pushDatabaseSchema, s as setupDatabase } from './database-setup-BdXiI4MV.js';
import { C as CLIError } from './cli-error-1drkrXNn.js';
import 'assert';
import 'events';
import 'module';
import 'node:buffer';
import 'conf';
import './logger-6V5cBxba.js';
import './spinner-DTH0QZQw.js';
import 'ora';
import './prompts-Beijr8dm.js';
import 'inquirer';

/**
 * Horizontal progress stepper - just the dots and labels
 *
 *     ●───────────●───────────○───────────○
 *   Setup      Install    Database    Finalize
 */
function ProgressStepper({ steps }) {
    const getStepColor = (status) => {
        switch (status) {
            case 'completed':
                return colors.success;
            case 'active':
                return colors.cyan;
            case 'error':
                return colors.error;
            default:
                return colors.dimGray;
        }
    };
    const getStepSymbol = (status) => {
        switch (status) {
            case 'error':
                return symbols.errorDot;
            case 'completed':
            case 'active':
                return symbols.filledDot;
            default:
                return symbols.hollowDot;
        }
    };
    // Cell and connector sizing
    const cellWidth = 10;
    const connectorWidth = 7;
    return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", alignItems: "center", children: [jsxRuntimeExports.jsx(Box, { children: steps.map((step, index) => (jsxRuntimeExports.jsxs(reactExports.Fragment, { children: [jsxRuntimeExports.jsx(Box, { width: cellWidth, justifyContent: "center", children: jsxRuntimeExports.jsx(Text, { color: getStepColor(step.status), children: getStepSymbol(step.status) }) }), index < steps.length - 1 && (jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: symbols.horizontalLine.repeat(connectorWidth) }))] }, step.id))) }), jsxRuntimeExports.jsx(Box, { children: steps.map((step, index) => (jsxRuntimeExports.jsxs(reactExports.Fragment, { children: [jsxRuntimeExports.jsx(Box, { width: cellWidth, justifyContent: "center", children: jsxRuntimeExports.jsx(Text, { color: step.status === 'pending' ? colors.dimGray : colors.gray, dimColor: step.status === 'pending', children: step.label }) }), index < steps.length - 1 && (jsxRuntimeExports.jsx(Box, { width: connectorWidth }))] }, step.id))) })] }));
}

// Match the stepper width: cellWidth(10) * 4 + connectorWidth(7) * 3 = 61
const BOX_WIDTH = 61;
const BOX_INNER_WIDTH = BOX_WIDTH - 4; // Account for "│ " and " │"
/**
 * TaskStream - Shows current step's tasks in a terminal-style box
 *
 * ┌───────────────────────────────────────────────────────────┐
 * │ ⠋ Configuring database                                    │
 * │   └── Setting up Neon database...▌                        │
 * └───────────────────────────────────────────────────────────┘
 */
function TaskStream({ stepId, tasks, onTypewriterComplete }) {
    const [spinnerIndex, setSpinnerIndex] = reactExports.useState(0);
    const [cursorVisible, setCursorVisible] = reactExports.useState(true);
    const [typedChars, setTypedChars] = reactExports.useState({});
    const [completedTyping, setCompletedTyping] = reactExports.useState(new Set());
    const prevStepRef = reactExports.useRef(stepId);
    // Reset typed chars when step changes
    reactExports.useEffect(() => {
        if (stepId !== prevStepRef.current) {
            setTypedChars({});
            setCompletedTyping(new Set());
            prevStepRef.current = stepId;
        }
    }, [stepId]);
    // Spinner animation - runs independently
    reactExports.useEffect(() => {
        let mounted = true;
        const animate = () => {
            if (!mounted)
                return;
            setSpinnerIndex(prev => (prev + 1) % symbols.spinnerFrames.length);
            setTimeout(animate, layout.spinnerInterval);
        };
        const timeout = setTimeout(animate, layout.spinnerInterval);
        return () => {
            mounted = false;
            clearTimeout(timeout);
        };
    }, []);
    // Cursor blink - runs independently  
    reactExports.useEffect(() => {
        let mounted = true;
        const blink = () => {
            if (!mounted)
                return;
            setCursorVisible(prev => !prev);
            setTimeout(blink, 400);
        };
        const timeout = setTimeout(blink, 400);
        return () => {
            mounted = false;
            clearTimeout(timeout);
        };
    }, []);
    // Find tasks by status
    const runningTask = tasks.find(t => t.status === 'running');
    const failedTask = tasks.find(t => t.status === 'failed');
    const completedTasks = tasks.filter(t => t.status === 'completed');
    // Primary task: running > failed > last completed (to prevent visual jump)
    const primaryTask = runningTask || failedTask || completedTasks[completedTasks.length - 1];
    // Previous completed tasks (all except the one shown as primary)
    const previousCompleted = primaryTask?.status === 'completed'
        ? completedTasks.slice(0, -1)
        : completedTasks;
    // Build display lines
    const lines = [];
    // Main task line (running, failed, or last completed)
    if (primaryTask) {
        const isRunning = primaryTask.status === 'running';
        const isCompleted = primaryTask.status === 'completed';
        primaryTask.status === 'failed';
        let prefix;
        let prefixColor;
        let textColor;
        if (isRunning) {
            prefix = `${symbols.spinnerFrames[spinnerIndex]} `;
            prefixColor = colors.cyan;
            textColor = colors.white;
        }
        else if (isCompleted) {
            prefix = `${symbols.check} `;
            prefixColor = colors.success;
            textColor = colors.white;
        }
        else {
            prefix = `${symbols.cross} `;
            prefixColor = colors.error;
            textColor = colors.error;
        }
        lines.push({
            id: `main-${primaryTask.id}`,
            text: primaryTask.label,
            displayedText: primaryTask.label,
            color: textColor,
            prefix,
            prefixColor,
            showCursor: false,
        });
    }
    // Previous completed tasks as subtasks - with green checkmark
    previousCompleted.forEach((task, index) => {
        const hasMore = primaryTask?.detail || primaryTask?.error || index < previousCompleted.length - 1;
        const connector = hasMore ? '├──' : '└──';
        lines.push({
            id: `completed-${task.id}`,
            text: task.label,
            displayedText: task.label,
            color: colors.white,
            prefix: `  ${connector} `,
            prefixColor: colors.dimGray,
            showCursor: false,
            checkmark: true,
        });
    });
    // Detail line (no typewriter for progress updates - show immediately)
    if (primaryTask?.detail && primaryTask.status === 'running') {
        lines.push({
            id: `detail-${primaryTask.id}`,
            text: primaryTask.detail,
            displayedText: primaryTask.detail, // Show full text immediately for progress updates
            color: colors.dimGray,
            prefix: '  └── ',
            prefixColor: colors.dimGray,
            showCursor: false, // No cursor for instant updates
        });
    }
    // Error line (typewriter effect)
    if (primaryTask?.error && primaryTask.status === 'failed') {
        const errorId = `error-${primaryTask.id}`;
        const currentChars = typedChars[errorId] || 0;
        const displayedText = primaryTask.error.slice(0, currentChars);
        const isTyping = currentChars < primaryTask.error.length;
        lines.push({
            id: errorId,
            text: primaryTask.error,
            displayedText,
            color: colors.error,
            prefix: '  └── ',
            prefixColor: colors.dimGray,
            showCursor: isTyping && cursorVisible,
        });
    }
    // Typewriter animation - only for errors now (details show instantly for progress)
    const errorToType = primaryTask?.error && primaryTask.status === 'failed' ? primaryTask.error : null;
    const textToType = errorToType;
    const typeId = errorToType ? `error-${primaryTask?.id}` : null;
    reactExports.useEffect(() => {
        if (!typeId || !textToType)
            return;
        const currentChars = typedChars[typeId] || 0;
        // Check if we just finished typing
        if (currentChars >= textToType.length) {
            // Fire callback once when typing completes
            if (!completedTyping.has(typeId) && onTypewriterComplete && primaryTask) {
                setCompletedTyping(prev => new Set(prev).add(typeId));
                onTypewriterComplete(primaryTask.id);
            }
            return;
        }
        // Continue typing animation
        const timeout = setTimeout(() => {
            setTypedChars(prev => ({
                ...prev,
                [typeId]: (prev[typeId] || 0) + 1,
            }));
        }, 30);
        return () => clearTimeout(timeout);
    }, [typeId, textToType, typedChars[typeId || ''], completedTyping, onTypewriterComplete, primaryTask]);
    // Empty state - show empty box to maintain layout
    if (lines.length === 0) {
        return (jsxRuntimeExports.jsx(Box, { flexDirection: "column", alignItems: "center", marginTop: 1, children: jsxRuntimeExports.jsxs(Box, { flexDirection: "column", width: BOX_WIDTH, children: [jsxRuntimeExports.jsxs(Text, { color: colors.dimGray, children: ["\u250C", '─'.repeat(BOX_WIDTH - 2), "\u2510"] }), jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: "\u2502" }), jsxRuntimeExports.jsx(Text, { children: ' '.repeat(BOX_WIDTH - 2) }), jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: "\u2502" })] }), jsxRuntimeExports.jsxs(Text, { color: colors.dimGray, children: ["\u2514", '─'.repeat(BOX_WIDTH - 2), "\u2518"] })] }) }));
    }
    return (jsxRuntimeExports.jsx(Box, { flexDirection: "column", alignItems: "center", marginTop: 1, children: jsxRuntimeExports.jsxs(Box, { flexDirection: "column", width: BOX_WIDTH, children: [jsxRuntimeExports.jsxs(Text, { color: colors.dimGray, children: ["\u250C", '─'.repeat(BOX_WIDTH - 2), "\u2510"] }), lines.map(line => {
                    const checkmarkStr = line.checkmark ? `${symbols.check} ` : '';
                    const content = `${line.prefix}${checkmarkStr}${line.displayedText}`;
                    const cursor = line.showCursor ? '▌' : '';
                    const paddingNeeded = Math.max(0, BOX_INNER_WIDTH - content.length - cursor.length);
                    return (jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: "\u2502 " }), jsxRuntimeExports.jsx(Text, { color: line.prefixColor, children: line.prefix }), line.checkmark && jsxRuntimeExports.jsxs(Text, { color: colors.success, children: [symbols.check, " "] }), jsxRuntimeExports.jsx(Text, { color: line.color, children: line.displayedText }), line.showCursor && jsxRuntimeExports.jsx(Text, { color: colors.cyan, children: "\u258C" }), jsxRuntimeExports.jsx(Text, { children: ' '.repeat(paddingNeeded) }), jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: " \u2502" })] }, line.id));
                }), jsxRuntimeExports.jsxs(Text, { color: colors.dimGray, children: ["\u2514", '─'.repeat(BOX_WIDTH - 2), "\u2518"] })] }) }));
}

/**
 * Configuration summary display
 * ───────────────────────────────────
 *  Workspace   ~/hatchway-workspace
 *  Server      http://localhost:3000
 *  Runner      local
 * ───────────────────────────────────
 */
function ConfigSummary({ items, title }) {
    const dividerWidth = 40;
    const divider = symbols.horizontalLine.repeat(dividerWidth);
    // Find the longest label for alignment
    const maxLabelLength = Math.max(...items.map(item => item.label.length));
    return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", alignItems: "center", children: [jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: divider }), title && (jsxRuntimeExports.jsx(Box, { marginTop: 1, marginBottom: 1, children: jsxRuntimeExports.jsx(Text, { color: colors.white, bold: true, children: title }) })), jsxRuntimeExports.jsx(Box, { flexDirection: "column", alignItems: "flex-start", marginTop: title ? 0 : 1, children: items.map((item, index) => (jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: colors.gray, children: item.label.padEnd(maxLabelLength + 3) }), jsxRuntimeExports.jsx(Text, { color: colors.cyan, children: item.value })] }, index))) }), jsxRuntimeExports.jsx(Box, { marginTop: 1, children: jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: divider }) })] }));
}
/**
 * Next steps display for completion screen
 */
function NextSteps({ command, url }) {
    return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", alignItems: "center", marginTop: 1, children: [jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: colors.gray, children: "Run:  " }), jsxRuntimeExports.jsx(Text, { color: colors.cyan, bold: true, children: command })] }), jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: colors.gray, children: "Open: " }), jsxRuntimeExports.jsx(Text, { color: colors.cyan, children: url })] })] }));
}
/**
 * Error display with message and recovery suggestions
 */
function ErrorSummary({ message, suggestions }) {
    const dividerWidth = 44;
    const divider = symbols.horizontalLine.repeat(dividerWidth);
    return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", alignItems: "center", children: [jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: divider }), message && (jsxRuntimeExports.jsx(Box, { marginTop: 1, marginBottom: 1, children: jsxRuntimeExports.jsxs(Text, { color: colors.error, bold: true, children: [symbols.cross, " ", message] }) })), jsxRuntimeExports.jsx(Box, { flexDirection: "column", alignItems: "flex-start", marginTop: message ? 0 : 1, children: suggestions.map((suggestion, index) => (jsxRuntimeExports.jsx(Box, { children: jsxRuntimeExports.jsx(Text, { color: suggestion.startsWith('  ') ? colors.cyan : colors.gray, children: suggestion }) }, index))) }), jsxRuntimeExports.jsx(Box, { marginTop: 1, children: jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: divider }) })] }));
}

/**
 * Compact build error viewer with scrolling and copy support
 * Displays in the center area, half-width, with scrollable content
 */
function BuildErrorView({ title, errorLines, suggestions = [], onExit }) {
    const { exit } = useApp();
    const { stdout } = useStdout();
    const terminalWidth = stdout?.columns || 80;
    const [scrollOffset, setScrollOffset] = reactExports.useState(0);
    const [showCopiedMessage, setShowCopiedMessage] = reactExports.useState(false);
    // Fixed dimensions for compact view
    const boxWidth = Math.min(70, Math.floor(terminalWidth * 0.6));
    const maxVisibleLines = 12; // Show 12 lines of errors max
    // Calculate max scroll
    const maxScroll = Math.max(0, errorLines.length - maxVisibleLines);
    // Get visible lines
    const visibleLines = errorLines.slice(scrollOffset, scrollOffset + maxVisibleLines);
    // Copy all error content to clipboard
    const copyToClipboard = reactExports.useCallback(async () => {
        const content = [
            `Build Error: ${title}`,
            '─'.repeat(60),
            ...errorLines,
            '─'.repeat(60),
            '',
            ...suggestions,
        ].join('\n');
        try {
            const { exec } = await import('child_process');
            // Detect platform and use appropriate clipboard command
            const platform = process.platform;
            let clipboardCmd;
            if (platform === 'darwin') {
                clipboardCmd = 'pbcopy';
            }
            else if (platform === 'win32') {
                clipboardCmd = 'clip';
            }
            else {
                clipboardCmd = 'xclip -selection clipboard';
            }
            // Write to clipboard
            const child = exec(clipboardCmd);
            child.stdin?.write(content);
            child.stdin?.end();
            setShowCopiedMessage(true);
            // Show success message then exit after delay
            setTimeout(() => {
                if (onExit) {
                    onExit();
                }
                else {
                    exit();
                }
            }, 1500);
        }
        catch (error) {
            // Clipboard failed - still show message
            setShowCopiedMessage(true);
            setTimeout(() => setShowCopiedMessage(false), 2000);
        }
    }, [title, errorLines, suggestions, onExit, exit]);
    // Handle keyboard input
    useInput((input, key) => {
        if (input === 'c' || input === 'C') {
            copyToClipboard();
        }
        else if (key.upArrow) {
            setScrollOffset(prev => Math.max(0, prev - 1));
        }
        else if (key.downArrow) {
            setScrollOffset(prev => Math.min(maxScroll, prev + 1));
        }
        else if (key.pageUp) {
            setScrollOffset(prev => Math.max(0, prev - maxVisibleLines));
        }
        else if (key.pageDown) {
            setScrollOffset(prev => Math.min(maxScroll, prev + maxVisibleLines));
        }
        else if (input === 'q' || key.escape) {
            if (onExit) {
                onExit();
            }
            else {
                exit();
            }
        }
    });
    // Color error lines based on content
    const getLineColor = (line) => {
        if (/error|Error|ERR!/i.test(line))
            return colors.error;
        if (/warning|warn/i.test(line))
            return colors.warning;
        if (/:\d+:\d+/.test(line))
            return colors.cyan;
        if (line.startsWith('─') || line.startsWith('hatchway:'))
            return colors.dimGray;
        return colors.gray;
    };
    const divider = symbols.horizontalLine.repeat(boxWidth - 2);
    const hasScroll = errorLines.length > maxVisibleLines;
    return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", alignItems: "center", width: "100%", children: [jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: divider }), jsxRuntimeExports.jsx(Box, { marginTop: 1, marginBottom: 1, width: boxWidth, justifyContent: "center", children: jsxRuntimeExports.jsxs(Text, { color: colors.error, bold: true, children: [symbols.cross, " ", title] }) }), jsxRuntimeExports.jsxs(Box, { flexDirection: "column", width: boxWidth, borderStyle: "round", borderColor: colors.error, paddingX: 1, paddingY: 0, children: [hasScroll && (jsxRuntimeExports.jsx(Box, { justifyContent: "flex-end", marginBottom: 0, children: jsxRuntimeExports.jsxs(Text, { color: colors.dimGray, dimColor: true, children: ["[", scrollOffset + 1, "-", Math.min(scrollOffset + maxVisibleLines, errorLines.length), "/", errorLines.length, "] \u2191\u2193"] }) })), visibleLines.length > 0 ? (visibleLines.map((line, index) => {
                        const truncatedLine = line.length > boxWidth - 4
                            ? line.substring(0, boxWidth - 7) + '...'
                            : line;
                        return (jsxRuntimeExports.jsx(Text, { color: getLineColor(line), wrap: "truncate", children: truncatedLine }, index));
                    })) : (jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: "No error details captured" }))] }), suggestions.length > 0 && (jsxRuntimeExports.jsx(Box, { flexDirection: "column", marginTop: 1, width: boxWidth, children: suggestions.map((suggestion, index) => (jsxRuntimeExports.jsx(Text, { color: suggestion.startsWith('  ') ? colors.cyan : colors.gray, children: suggestion }, index))) })), jsxRuntimeExports.jsx(Box, { marginTop: 1, children: jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: divider }) }), jsxRuntimeExports.jsx(Box, { marginTop: 1, justifyContent: "center", children: showCopiedMessage ? (jsxRuntimeExports.jsxs(Text, { color: colors.success, bold: true, children: [symbols.check, " Copied to clipboard! Exiting..."] })) : (jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: "[" }), jsxRuntimeExports.jsx(Text, { color: colors.success, bold: true, children: "c" }), jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: "]" }), jsxRuntimeExports.jsx(Text, { color: colors.success, children: "copy & exit" }), jsxRuntimeExports.jsx(Text, { children: "  " }), jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: "[" }), jsxRuntimeExports.jsx(Text, { color: colors.cyan, children: "q" }), jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: "]" }), jsxRuntimeExports.jsx(Text, { color: colors.gray, children: "quit" }), hasScroll && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Text, { children: "  " }), jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: "[" }), jsxRuntimeExports.jsx(Text, { color: colors.cyan, children: "\u2191\u2193" }), jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: "]" }), jsxRuntimeExports.jsx(Text, { color: colors.gray, children: "scroll" })] }))] })) })] }));
}

const INITIAL_STEPS = [
    { id: 'repo', label: 'Clone', status: 'pending' },
    { id: 'build', label: 'Build', status: 'pending' },
    { id: 'database', label: 'Configure', status: 'pending' },
    { id: 'ready', label: 'Finish', status: 'pending' },
];
// Tasks now have a stepId to associate them with a step
const INITIAL_TASKS = [
    { id: 'clone', label: 'Cloning repository', status: 'pending', stepId: 'repo' },
    { id: 'deps', label: 'Installing dependencies', status: 'pending', stepId: 'build' },
    { id: 'build', label: 'Building packages', status: 'pending', stepId: 'build' },
    { id: 'database', label: 'Configuring database', status: 'pending', stepId: 'database' },
    { id: 'config', label: 'Saving configuration', status: 'pending', stepId: 'ready' },
    { id: 'services', label: 'Building services', status: 'pending', stepId: 'ready' },
];
function useInitFlow() {
    const [state, setState] = reactExports.useState({
        phase: 'repo',
        steps: INITIAL_STEPS,
        tasks: INITIAL_TASKS,
        config: [],
        error: null,
        isComplete: false,
    });
    // Step management
    const setStepStatus = reactExports.useCallback((stepId, status) => {
        setState(prev => ({
            ...prev,
            steps: prev.steps.map(step => step.id === stepId ? { ...step, status } : step),
        }));
    }, []);
    const activateStep = reactExports.useCallback((stepId) => {
        setState(prev => ({
            ...prev,
            phase: stepId,
            steps: prev.steps.map(step => step.id === stepId ? { ...step, status: 'active' } : step),
        }));
    }, []);
    const completeStep = reactExports.useCallback((stepId) => {
        setStepStatus(stepId, 'completed');
    }, [setStepStatus]);
    const failStep = reactExports.useCallback((stepId) => {
        setStepStatus(stepId, 'error');
    }, [setStepStatus]);
    // Task management
    const setTaskStatus = reactExports.useCallback((taskId, status, detail) => {
        setState(prev => ({
            ...prev,
            tasks: prev.tasks.map(task => task.id === taskId ? { ...task, status, detail: detail ?? task.detail } : task),
        }));
    }, []);
    const startTask = reactExports.useCallback((taskId, detail) => {
        setTaskStatus(taskId, 'running', detail);
    }, [setTaskStatus]);
    const completeTask = reactExports.useCallback((taskId) => {
        setTaskStatus(taskId, 'completed');
    }, [setTaskStatus]);
    const failTask = reactExports.useCallback((taskId, error) => {
        setState(prev => ({
            ...prev,
            tasks: prev.tasks.map(task => task.id === taskId ? { ...task, status: 'failed', error } : task),
        }));
    }, []);
    // Get tasks for a specific step
    const getTasksForStep = reactExports.useCallback((stepId) => {
        return state.tasks.filter(task => task.stepId === stepId);
    }, [state.tasks]);
    // Get tasks for the currently active step
    const getActiveStepTasks = reactExports.useCallback(() => {
        return state.tasks.filter(task => task.stepId === state.phase);
    }, [state.tasks, state.phase]);
    // Config management
    const setConfig = reactExports.useCallback((items) => {
        setState(prev => ({
            ...prev,
            config: items,
        }));
    }, []);
    // Error management
    const setError = reactExports.useCallback((message, suggestions) => {
        setState(prev => ({
            ...prev,
            error: { message, suggestions },
        }));
    }, []);
    const setBuildError = reactExports.useCallback((message, errorLines, suggestions) => {
        setState(prev => ({
            ...prev,
            error: {
                message,
                suggestions,
                buildError: {
                    errorLines,
                    suggestions,
                }
            },
        }));
    }, []);
    const clearError = reactExports.useCallback(() => {
        setState(prev => ({
            ...prev,
            error: null,
        }));
    }, []);
    // Completion
    const markComplete = reactExports.useCallback(() => {
        setState(prev => ({
            ...prev,
            isComplete: true,
            phase: 'ready',
            steps: prev.steps.map(step => ({ ...step, status: 'completed' })),
        }));
    }, []);
    // Reset
    const reset = reactExports.useCallback(() => {
        setState({
            phase: 'repo',
            steps: INITIAL_STEPS,
            tasks: INITIAL_TASKS,
            config: [],
            error: null,
            isComplete: false,
        });
    }, []);
    return {
        state,
        setStepStatus,
        activateStep,
        completeStep,
        failStep,
        setTaskStatus,
        startTask,
        completeTask,
        failTask,
        getTasksForStep,
        getActiveStepTasks,
        setConfig,
        setError,
        setBuildError,
        clearError,
        markComplete,
        reset,
    };
}

/**
 * Main init screen - fullscreen centered TUI
 * Shows progress stepper with tasks appearing under the active step
 */
function InitScreen({ onInit, onComplete, onError }) {
    const { exit } = useApp();
    const { stdout } = useStdout();
    const flow = useInitFlow();
    const [finalConfig, setFinalConfig] = reactExports.useState(null);
    // Get version info
    const versionInfo = getVersionInfo();
    // Calculate vertical centering
    const terminalHeight = stdout?.rows || 24;
    const contentHeight = 20;
    const topPadding = Math.max(0, Math.floor((terminalHeight - contentHeight) / 3));
    // Run init flow
    reactExports.useEffect(() => {
        const callbacks = {
            activateStep: flow.activateStep,
            completeStep: flow.completeStep,
            failStep: flow.failStep,
            startTask: flow.startTask,
            completeTask: flow.completeTask,
            failTask: flow.failTask,
            skipTask: (taskId) => {
                flow.setTaskStatus(taskId, 'completed');
            },
            updateTaskLabel: (taskId, label) => {
                flow.setTaskStatus(taskId, flow.state.tasks.find(t => t.id === taskId)?.status || 'pending');
            },
            setError: flow.setError,
            setBuildError: flow.setBuildError,
        };
        onInit(callbacks)
            .then((config) => {
            setFinalConfig(config);
            // Set config summary items
            const configItems = [
                { label: 'Workspace', value: config.workspace },
                { label: 'Server', value: config.apiUrl },
                { label: 'Runner', value: config.runnerId },
            ];
            if (config.monorepoPath) {
                configItems.push({ label: 'Repository', value: config.monorepoPath });
            }
            flow.setConfig(configItems);
            flow.markComplete();
            if (onComplete) {
                onComplete(config);
            }
        })
            .catch((error) => {
            if (onError) {
                onError(error);
            }
        });
    }, []);
    const { state } = flow;
    // Get tasks for current step only, mapped to StreamTask format
    const currentStepTasks = flow.getActiveStepTasks().map(task => ({
        id: task.id,
        label: task.label,
        status: task.status,
        detail: task.detail,
        error: task.error,
    }));
    return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", alignItems: "center", paddingTop: topPadding, children: [jsxRuntimeExports.jsx(Banner, {}), jsxRuntimeExports.jsx(Box, { marginTop: 1, children: jsxRuntimeExports.jsx(Text, { color: colors.gray, dimColor: true, children: versionInfo.display }) }), jsxRuntimeExports.jsx(Box, { marginTop: 1 }), jsxRuntimeExports.jsx(ProgressStepper, { steps: state.steps }), !state.isComplete && !state.error && (jsxRuntimeExports.jsx(TaskStream, { stepId: state.phase, tasks: currentStepTasks })), state.error && state.error.buildError && (jsxRuntimeExports.jsx(BuildErrorView, { title: state.error.message, errorLines: state.error.buildError.errorLines, suggestions: state.error.buildError.suggestions, onExit: () => exit() })), state.error && !state.error.buildError && (jsxRuntimeExports.jsx(Box, { marginTop: 2, children: jsxRuntimeExports.jsx(ErrorSummary, { message: state.error.message, suggestions: state.error.suggestions }) })), state.isComplete && !state.error && (jsxRuntimeExports.jsxs(Box, { marginTop: 2, flexDirection: "column", alignItems: "center", children: [jsxRuntimeExports.jsxs(Text, { color: colors.success, bold: true, children: [symbols.check, " Setup complete!"] }), jsxRuntimeExports.jsx(Box, { marginTop: 1, flexDirection: "column", children: state.tasks.filter(t => t.status === 'completed').map(task => (jsxRuntimeExports.jsxs(Box, { children: [jsxRuntimeExports.jsx(Text, { color: colors.success, children: symbols.check }), jsxRuntimeExports.jsxs(Text, { color: colors.gray, children: [" ", task.label] })] }, task.id))) }), jsxRuntimeExports.jsx(Box, { marginTop: 1 }), jsxRuntimeExports.jsx(ConfigSummary, { items: state.config }), jsxRuntimeExports.jsx(NextSteps, { command: "hatchway run", url: "http://localhost:3000" })] }))] }));
}

/**
 * Post-init prompt asking if user wants to start Hatchway now
 */
function StartPromptScreen({ onSelect }) {
    const { stdout } = useStdout();
    // Calculate vertical centering
    const terminalHeight = stdout?.rows || 24;
    const contentHeight = 14;
    const topPadding = Math.max(0, Math.floor((terminalHeight - contentHeight) / 3));
    useInput((input, key) => {
        const char = input.toLowerCase();
        // Enter = start
        if (key.return) {
            onSelect(true);
            return;
        }
        // Y = start
        if (char === 'y') {
            onSelect(true);
            return;
        }
        // N = don't start
        if (char === 'n') {
            onSelect(false);
            return;
        }
        // Escape = don't start
        if (key.escape) {
            onSelect(false);
            return;
        }
    });
    return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", alignItems: "center", paddingTop: topPadding, children: [jsxRuntimeExports.jsx(Banner, {}), jsxRuntimeExports.jsx(Box, { marginTop: 2 }), jsxRuntimeExports.jsx(Box, { flexDirection: "column", alignItems: "center", children: jsxRuntimeExports.jsxs(Text, { color: colors.success, bold: true, children: [symbols.check, " Hatchway is ready!"] }) }), jsxRuntimeExports.jsx(Box, { marginTop: 2 }), jsxRuntimeExports.jsxs(Box, { flexDirection: "column", alignItems: "center", children: [jsxRuntimeExports.jsx(Text, { color: colors.white, children: "Start Hatchway now?" }), jsxRuntimeExports.jsx(Box, { marginTop: 1, children: jsxRuntimeExports.jsxs(Text, { color: colors.dimGray, children: ["Press ", jsxRuntimeExports.jsx(Text, { color: colors.cyan, bold: true, children: "Y" }), " or ", jsxRuntimeExports.jsx(Text, { color: colors.cyan, bold: true, children: "Enter" }), " to start, ", jsxRuntimeExports.jsx(Text, { color: colors.cyan, bold: true, children: "N" }), " or ", jsxRuntimeExports.jsx(Text, { color: colors.cyan, bold: true, children: "Esc" }), " to exit"] }) })] }), jsxRuntimeExports.jsx(Box, { marginTop: 2 }), jsxRuntimeExports.jsx(Box, { flexDirection: "column", alignItems: "center", children: jsxRuntimeExports.jsxs(Text, { color: colors.dimGray, children: ["To start later, run: ", jsxRuntimeExports.jsx(Text, { color: colors.cyan, children: "hatchway run" })] }) })] }));
}

/**
 * Init App component that manages the init flow screens
 */
function InitApp({ onInit, onComplete, onError }) {
    const [screen, setScreen] = reactExports.useState('init');
    const [config, setConfig] = reactExports.useState(null);
    const handleInitComplete = (initConfig) => {
        setConfig(initConfig);
        // Show the start prompt screen
        setScreen('prompt');
    };
    const handleStartChoice = (shouldStart) => {
        if (config) {
            onComplete(config, shouldStart);
        }
    };
    if (screen === 'prompt' && config) {
        return jsxRuntimeExports.jsx(StartPromptScreen, { onSelect: handleStartChoice });
    }
    return (jsxRuntimeExports.jsx(InitScreen, { onInit: onInit, onComplete: handleInitComplete, onError: onError }));
}
/**
 * Render the TUI init screen
 * Returns a promise that resolves with config and whether to start
 */
async function runInitTUI(options) {
    return new Promise((resolve, reject) => {
        let result = null;
        let error = null;
        const { unmount, waitUntilExit } = render(jsxRuntimeExports.jsx(InitApp, { onInit: options.onInit, onComplete: (config, shouldStart) => {
                result = { config, shouldStart };
                // Give time for final render before unmounting
                setTimeout(() => {
                    unmount();
                }, 100);
            }, onError: (err) => {
                error = err;
                // Keep error displayed, don't auto-unmount
            } }), {
            exitOnCtrlC: true,
        });
        waitUntilExit().then(() => {
            if (error) {
                reject(error);
            }
            else if (result) {
                resolve(result);
            }
            else {
                reject(new Error('Init cancelled'));
            }
        });
    });
}

/**
 * TUI-based init command with beautiful centered interface
 * Uses Ink for React-based terminal rendering
 */
/**
 * Generate a secure random secret
 */
function generateSecret() {
    return randomBytes(32).toString('hex');
}
/**
 * Check if a path is or contains the current working directory
 */
function isCurrentWorkingDirectory(targetPath) {
    try {
        const cwd = realpathSync(process.cwd());
        const target = realpathSync(resolve(targetPath));
        return cwd === target || cwd.startsWith(target + '/');
    }
    catch {
        const cwd = process.cwd();
        const target = resolve(targetPath);
        return cwd === target || cwd.startsWith(target + '/');
    }
}
/**
 * Normalize URL by adding protocol if missing
 */
function normalizeUrl(url) {
    if (url.match(/^https?:\/\//i))
        return url;
    if (url.match(/^(localhost|127\.0\.0\.1)(:|\/|$)/i)) {
        return `http://${url}`;
    }
    return `https://${url}`;
}
/**
 * Get default workspace path
 */
function getDefaultWorkspace() {
    return join(process.cwd(), 'hatchway-workspace');
}
/**
 * Get default monorepo clone path
 */
function getDefaultMonorepoPath() {
    return join(process.cwd(), 'hatchway');
}
/**
 * Sleep utility for deliberate pacing
 */
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
/**
 * Run the TUI-based init command
 */
async function initTUICommand(options) {
    // Enable silent mode right before TUI renders
    // This prevents console output from bleeding into the TUI
    process.env.SILENT_MODE = '1';
    // Clear screen for fullscreen experience
    console.clear();
    try {
        const { shouldStart } = await runInitTUI({
            onInit: async (callbacks) => {
                return executeInitFlow(options, callbacks);
            },
        });
        if (shouldStart) {
            console.clear();
            console.log('\n  Starting Hatchway...\n');
            // Import and run the start command (full TUI with web app + runner)
            const { startCommand } = await import('./start-Dkuro1jp.js');
            await startCommand({});
        }
        else {
            console.clear();
            console.log('\n  ✨ Hatchway is ready!\n');
            console.log('  To start later, run:\n');
            console.log('    hatchway run\n');
            console.log('  Then open: http://localhost:3000\n');
        }
    }
    catch (error) {
        // Display error if it wasn't shown in TUI
        // CLIErrors from the init flow are shown in TUI, but errors from startCommand are not
        console.clear();
        if (error instanceof CLIError) {
            console.error('\n  Error: ' + error.message + '\n');
            if (error.suggestions && error.suggestions.length > 0) {
                console.error('  Suggestions:');
                error.suggestions.forEach((s) => console.error('    - ' + s));
                console.error('');
            }
        }
        else if (error instanceof Error) {
            console.error('\n  Error: ' + error.message + '\n');
        }
        else {
            console.error('\n  An unexpected error occurred\n');
        }
        process.exit(1);
    }
}
/**
 * Execute the init flow, calling callbacks to update UI
 */
async function executeInitFlow(options, callbacks) {
    const { activateStep, completeStep, failStep, startTask, completeTask, failTask, setError, setBuildError } = callbacks;
    let monorepoPath;
    let databaseUrl;
    const workspace = options.workspace || getDefaultWorkspace();
    const generatedSecret = options.secret || generateSecret();
    const apiUrl = normalizeUrl(options.url || 'http://localhost:3000');
    // ============================================
    // PHASE 1: Repository
    // ============================================
    activateStep('repo');
    await sleep(layout.stepTransitionDelay);
    // Reset config if exists
    if (configManager.isInitialized()) {
        configManager.reset();
    }
    // Check for existing monorepo
    startTask('clone', 'Checking for repository...');
    await sleep(300);
    const repoCheck = await isInsideMonorepo();
    if (repoCheck.inside && repoCheck.root) {
        monorepoPath = repoCheck.root;
        completeTask('clone');
        await sleep(layout.taskCompletionDelay);
    }
    else {
        // Need to clone
        const hasPnpm = await isPnpmInstalled();
        if (!hasPnpm) {
            failTask('clone', 'pnpm not found');
            failStep('repo');
            setError('pnpm is required', [
                'Install pnpm:  npm install -g pnpm',
                'Then retry:    hatchway init -y',
            ]);
            throw new CLIError({
                code: 'DEPENDENCIES_INSTALL_FAILED',
                message: 'pnpm is not installed',
            });
        }
        const clonePath = getDefaultMonorepoPath();
        // Clean up existing installation
        if (existsSync(clonePath)) {
            if (isCurrentWorkingDirectory(clonePath)) {
                failTask('clone', 'Cannot remove current directory');
                failStep('repo');
                setError('Cannot remove current directory', [
                    'Run from a different directory',
                    'Or manually remove: rm -rf ' + clonePath,
                ]);
                throw new CLIError({
                    code: 'CONFIG_INVALID',
                    message: 'Cannot remove current working directory',
                });
            }
            rmSync(clonePath, { recursive: true, force: true });
        }
        try {
            // Clone repository
            startTask('clone', 'Cloning from GitHub...');
            monorepoPath = await cloneRepository({
                targetPath: clonePath,
                branch: options.branch || 'main',
                silent: true, // Suppress console output in TUI mode
            });
            completeTask('clone');
            await sleep(layout.taskCompletionDelay);
        }
        catch (error) {
            failTask('clone', 'Clone failed');
            failStep('repo');
            setError('Failed to clone repository', [
                'Check your internet connection',
                'Verify git is installed: git --version',
                'Try: git clone https://github.com/codyde/hatchway.git',
            ]);
            throw error;
        }
    }
    completeStep('repo');
    await sleep(layout.stepTransitionDelay);
    // ============================================
    // PHASE 2: Build
    // ============================================
    activateStep('build');
    await sleep(layout.stepTransitionDelay);
    // Install dependencies
    startTask('deps', 'Running pnpm install...');
    try {
        await installDependencies(monorepoPath, true); // silent mode
        completeTask('deps');
        await sleep(layout.taskCompletionDelay);
    }
    catch (error) {
        failTask('deps', 'Install failed');
        failStep('build');
        setError('Failed to install dependencies', [
            'Check pnpm is installed: pnpm --version',
            'Try manually: cd ' + monorepoPath + ' && pnpm install',
        ]);
        throw error;
    }
    // Build packages
    startTask('build', '@hatchway/agent-core');
    try {
        await buildAgentCore(monorepoPath, true); // silent mode
        completeTask('build');
        await sleep(layout.taskCompletionDelay);
    }
    catch (error) {
        failTask('build', 'Build failed');
        failStep('build');
        setError('Failed to build packages', [
            'Try manually: cd ' + monorepoPath + ' && pnpm build',
        ]);
        throw error;
    }
    completeStep('build');
    await sleep(layout.stepTransitionDelay);
    // ============================================
    // PHASE 3: Database
    // ============================================
    activateStep('database');
    await sleep(layout.stepTransitionDelay);
    startTask('database', 'Setting up Neon database...');
    // Handle database options
    const dbOption = options.database;
    const isConnectionString = typeof dbOption === 'string' &&
        (dbOption.startsWith('postgres://') || dbOption.startsWith('postgresql://'));
    try {
        if (isConnectionString) {
            databaseUrl = dbOption;
            await pushDatabaseSchema(monorepoPath, databaseUrl, true); // silent mode
        }
        else {
            // Default: setup Neon database
            databaseUrl = await setupDatabase(monorepoPath, true) || undefined; // silent mode
            if (databaseUrl) {
                await pushDatabaseSchema(monorepoPath, databaseUrl, true); // silent mode
            }
        }
        // Verify we got a database URL - it's required for the app to work
        if (!databaseUrl) {
            throw new Error('Database setup did not return a connection URL');
        }
        completeTask('database');
        await sleep(layout.taskCompletionDelay);
    }
    catch (error) {
        // Database setup failed - this is a critical error
        const errorMessage = error instanceof Error ? error.message : 'Unknown error';
        failTask('database', 'Setup failed');
        failStep('database');
        setError('Database setup failed', [
            errorMessage,
            '',
            'You can provide your own database:',
            '  hatchway init --database postgres://...',
            '',
            'Or set it manually later:',
            '  hatchway config set databaseUrl postgres://...',
        ]);
        throw new CLIError({
            code: 'DB_CONNECTION_FAILED',
            message: 'Failed to setup database: ' + errorMessage,
        });
    }
    completeStep('database');
    await sleep(layout.stepTransitionDelay);
    // ============================================
    // PHASE 4: Configuration & Ready
    // ============================================
    activateStep('ready');
    await sleep(layout.stepTransitionDelay);
    // Create workspace directory
    if (!existsSync(workspace)) {
        await mkdir(workspace, { recursive: true });
    }
    // Save configuration
    startTask('config', 'Writing configuration...');
    try {
        configManager.set('workspace', workspace);
        if (monorepoPath) {
            configManager.set('monorepoPath', monorepoPath);
        }
        if (databaseUrl) {
            configManager.set('databaseUrl', databaseUrl);
        }
        configManager.set('apiUrl', apiUrl);
        const wsProtocol = apiUrl.startsWith('https://') ? 'wss://' : 'ws://';
        const hostPath = apiUrl.replace(/^https?:\/\//, '').replace(/\/$/, '');
        const wsUrl = `${wsProtocol}${hostPath}/ws/runner`;
        configManager.set('server', {
            wsUrl: wsUrl,
            secret: generatedSecret,
        });
        configManager.set('runner', {
            id: 'local',
            reconnectAttempts: 5,
            heartbeatInterval: 15000,
        });
        configManager.set('tunnel', {
            provider: 'cloudflare',
            autoCreate: true,
        });
        // Create .env.local
        if (monorepoPath) {
            const envLocalPath = join(monorepoPath, 'apps', 'hatchway', '.env.local');
            const envContent = [
                '# Auto-generated by hatchway CLI',
                `# Generated at: ${new Date().toISOString()}`,
                '',
                'HATCHWAY_LOCAL_MODE=true',
                `RUNNER_SHARED_SECRET=${generatedSecret}`,
                `WORKSPACE_ROOT=${workspace}`,
                'RUNNER_ID=local',
                'RUNNER_DEFAULT_ID=local',
                `DATABASE_URL=${databaseUrl || ''}`,
                '',
            ].join('\n');
            await writeFile(envLocalPath, envContent);
        }
        completeTask('config');
        await sleep(layout.taskCompletionDelay);
    }
    catch (error) {
        failTask('config', 'Config save failed');
        failStep('ready');
        setError('Failed to save configuration', [
            'Check file permissions',
            'Try running from a different directory',
        ]);
        throw error;
    }
    // Build all services for production
    if (monorepoPath) {
        startTask('services', 'Building services (this may take a minute)...');
        // Track build output for error reporting (capture both stdout and stderr)
        let buildOutput = '';
        let buildError = '';
        try {
            const { spawn } = await import('child_process');
            await new Promise((resolve, reject) => {
                const buildProcess = spawn('pnpm', ['build:all'], {
                    cwd: monorepoPath,
                    stdio: 'pipe',
                    shell: true,
                });
                // Capture stdout - many build tools output errors here
                buildProcess.stdout?.on('data', (data) => {
                    buildOutput += data.toString();
                });
                // Capture stderr
                buildProcess.stderr?.on('data', (data) => {
                    buildError += data.toString();
                });
                buildProcess.on('close', (code) => {
                    if (code === 0)
                        resolve();
                    else
                        reject(new Error(`Build failed with code ${code}`));
                });
                buildProcess.on('error', reject);
            });
            completeTask('services');
            await sleep(layout.taskCompletionDelay);
        }
        catch (error) {
            // Build failed - surface the error to the user
            failTask('services', 'Build failed');
            failStep('ready');
            // Combine all output for analysis
            const allOutput = (buildOutput + '\n' + buildError).trim();
            const allLines = allOutput.split('\n');
            // Find the most relevant error lines with better patterns
            const errorPatterns = [
                /error TS\d+:/i, // TypeScript errors
                /error:/i, // General errors
                /Error:/, // Error messages
                /ERR!/, // npm/pnpm errors
                /failed/i, // Failed messages
                /Cannot find/i, // Module not found
                /Module not found/i, // Webpack/Next.js errors
                /SyntaxError/i, // Syntax errors
                /TypeError/i, // Type errors
                /ReferenceError/i, // Reference errors
                /ENOENT/i, // File not found
                /✖|✗|×/, // Error symbols
            ];
            // Find lines that match error patterns
            const relevantLines = [];
            let inErrorBlock = false;
            for (let i = 0; i < allLines.length; i++) {
                const line = allLines[i];
                const isErrorLine = errorPatterns.some(pattern => pattern.test(line));
                if (isErrorLine) {
                    inErrorBlock = true;
                    // Include 1 line before for context if available
                    if (i > 0 && relevantLines.length === 0) {
                        const prevLine = allLines[i - 1].trim();
                        if (prevLine && !prevLine.startsWith('>')) {
                            relevantLines.push(prevLine);
                        }
                    }
                }
                if (inErrorBlock) {
                    relevantLines.push(line.trim());
                    // Collect more lines for scrollable view (max 50 lines)
                    if (relevantLines.length >= 50)
                        break;
                }
                // End error block on empty line or success indicators
                if (inErrorBlock && (line.trim() === '' || /successfully|completed/i.test(line))) {
                    // Keep going in case there are more errors
                    inErrorBlock = false;
                }
            }
            // If no specific errors found, show last 30 lines of output
            const displayLines = relevantLines.length > 0
                ? relevantLines
                : allLines.slice(-30);
            const suggestions = [
                'To debug further, run manually:',
                `  cd ${monorepoPath} && pnpm build:all`,
                '',
                'Common fixes:',
                '  - Run: pnpm install (missing dependencies)',
                '  - Check for TypeScript errors in the files mentioned above',
                '  - Ensure all environment variables are set',
            ];
            // Use setBuildError to show full-screen scrollable error view
            setBuildError('Production build failed', displayLines, suggestions);
            throw new CLIError({
                code: 'BUILD_FAILED',
                message: 'Failed to build services for production',
                suggestions: [
                    `Run manually: cd ${monorepoPath} && pnpm build:all`,
                    'Check for TypeScript errors in the output above',
                    'Ensure all dependencies are installed: pnpm install',
                ],
            });
        }
    }
    // Validate configuration
    const validation = configManager.validate();
    if (!validation.valid) {
        failStep('ready');
        setError('Configuration invalid', validation.errors);
        throw new CLIError({
            code: 'CONFIG_INVALID',
            message: 'Configuration validation failed',
        });
    }
    completeStep('ready');
    return {
        workspace,
        monorepoPath,
        databaseUrl,
        apiUrl,
        runnerId: 'local',
    };
}

export { initTUICommand };
//# sourceMappingURL=init-tui-m2supRiJ.js.map
