import pc from 'picocolors';
// ─── Brand colors ────────────────────────────────────
export const brand = (text) => pc.cyan(text);
export const dim = (text) => pc.dim(text);
export const success = (text) => pc.green(text);
export const warn = (text) => pc.yellow(text);
export const errorColor = (text) => pc.red(text);
export const bold = (text) => pc.bold(text);
// ─── Logging (all → stderr) ─────────────────────────
function prefix(tag) {
    return brand(`[${tag}]`);
}
export const log = {
    info(tag, msg) {
        console.error(`${prefix(tag)} ${msg}`);
    },
    success(tag, msg) {
        console.error(`${prefix(tag)} ${success(msg)}`);
    },
    warn(tag, msg) {
        console.error(`${prefix(tag)} ${warn(msg)}`);
    },
    error(tag, msg) {
        console.error(`${prefix(tag)} ${errorColor(msg)}`);
    },
    dim(tag, msg) {
        console.error(`${prefix(tag)} ${dim(msg)}`);
    },
};
import { getRandomSpinnerQuote } from './ui/quotes.js'; // totem-ignore — ui.ts is a shared utility, not a command file
/**
 * Custom spinner frame resembling an Inception spinning top wobbling.
 */
const INCEPTION_TOP = {
    interval: 100,
    frames: ['◐', '◓', '◑', '◒'],
};
/**
 * Create a spinner that writes to stderr.
 * Falls back to static log lines in non-TTY environments (CI, piped).
 */
export async function createSpinner(tag, text) {
    const isTTY = !!process.stderr.isTTY;
    const isQuoteMode = !text; // If no text provided, we cycle quotes
    let currentText = text || getRandomSpinnerQuote();
    if (!isTTY) {
        // Non-interactive: static log lines
        console.error(`${prefix(tag)} ${currentText}`);
        return {
            update(newText) {
                console.error(`${prefix(tag)} ${newText}`);
            },
            succeed(doneText) {
                if (doneText)
                    console.error(`${prefix(tag)} ${doneText}`);
            },
            fail(errText) {
                if (errText)
                    console.error(`${prefix(tag)} ${errText}`);
            },
            stop() { },
        };
    }
    // Dynamic import to keep startup fast for non-spinner commands
    const ora = (await import('ora')).default;
    const spinner = ora({
        text: `${prefix(tag)} ${currentText}`,
        stream: process.stderr,
        spinner: INCEPTION_TOP,
    }).start();
    let quoteInterval = null;
    // Cycle quotes every 45 seconds if we are in quote mode — let them breathe
    if (isQuoteMode) {
        quoteInterval = setInterval(() => {
            currentText = getRandomSpinnerQuote();
            spinner.text = `${prefix(tag)} ${currentText}`;
        }, 45_000);
    }
    const cleanup = () => {
        if (quoteInterval)
            clearInterval(quoteInterval);
    };
    return {
        update(newText) {
            if (isQuoteMode)
                return; // Don't let external progress updates overwrite our movie quotes if in quote mode
            spinner.text = `${prefix(tag)} ${newText}`;
        },
        succeed(doneText) {
            cleanup();
            spinner.succeed(doneText ? `${prefix(tag)} ${doneText}` : undefined);
        },
        fail(errText) {
            cleanup();
            spinner.fail(errText ? `${prefix(tag)} ${errText}` : undefined);
        },
        stop() {
            cleanup();
            spinner.stop();
        },
    };
}
// ─── Banner ──────────────────────────────────────────
const BANNER = `
  ${brand('╔╦╗╔═╗╔╦╗╔═╗╔╦╗')}
  ${brand(' ║ ║ ║ ║ ║╣ ║║║')}
  ${brand(' ╩ ╚═╝ ╩ ╚═╝╩ ╩')}
  ${dim('Your AI forgets. Totem remembers.')}
`;
export function printBanner() {
    console.error(BANNER);
}
//# sourceMappingURL=ui.js.map