{"version":3,"sources":["../src/screen/index.js","../src/screen/screens.js","../src/screen/components.js","../src/screen/screen-layout.js","../src/screen/visible-text.js","../src/screen/list-components.js","../src/screen/scrollbar.js","../src/screen/key-bindings.js","../src/screen/flicker-free-stdout.js","../src/screen/ui-elements.js","../src/screen/scrollable-text.js","../src/screen/follow-scroll.js","../src/screen/text-input.js","../src/screen/utils.js","../src/screen/footer-builder.js"],"sourcesContent":["/**\n * Screen System - Action-based architecture\n * Converted from legacy/screenSystem/src\n */\n\n// Re-export React and React hooks (encapsulated)\nimport React, { useState, useEffect, useLayoutEffect, useRef, useMemo, useCallback, memo, createElement } from \"react\";\nexport { React, useState, useEffect, useLayoutEffect, useRef, useMemo, useCallback, memo };\nexport { createElement as h };\n\n// Re-export Ink components (encapsulated)\nexport { Box, Text, useInput } from \"ink\";\n\n// Screen functions\nexport {\n    showScreen,\n    showListScreen,\n    showMultiColumnListScreen,\n    showMultiColumnListWithPreviewScreen,\n    // Backward compatibility aliases\n    showMenuScreen,\n    showWordGridScreen,\n    formatFooterHotkey,\n    formatKeyBindings,\n    bindingsToFooterHotkeys,\n    FOOTER_HOTKEY_STYLE,\n    FOOTER_MUTED_STYLE,\n    styleFooterHotkey,\n    styleFooterMuted,\n} from \"./screens.js\";\n\n// Reusable components\nexport { MultiColumnListComponent, MultiColumnListWithPreviewComponent, ListComponent } from \"./list-components.js\";\nexport { ScreenContainer, ScreenRow, ScreenTitle, ScreenBody, ScreenFooter, ScreenDivider, normalizeFooterHotkey } from \"./components.js\";\nexport {\n    getScreenBodyRows,\n    getScreenChromeRows,\n    getScreenFrameBoxHeight,\n} from \"./screen-layout.js\";\nexport { ListItem, TextBlock, Divider, GridCell, InputField } from \"./ui-elements.js\";\nexport { ScrollableText, wrapTextLines, scrollbarGlyphs } from \"./scrollable-text.js\";\nexport { createFlickerFreeStdout } from \"./flicker-free-stdout.js\";\nexport { stripAnsi, visibleWidth, padEndVisible, sliceVisible } from \"./visible-text.js\";\nexport {\n    clampScroll,\n    isScrolledToBottom,\n    nextScrollAfterUserMove,\n    nextScrollAfterContentChange,\n} from \"./follow-scroll.js\";\nexport {\n    PAGE_SCROLL_KEY_BINDINGS,\n    BAR_THUMB,\n    BAR_TRACK,\n} from \"./scrollbar.js\";\nexport {\n    bindingIdentity,\n    bindingMatchesInput,\n    formatBindingKey,\n} from \"./key-bindings.js\";\nexport { nextTextInputValue, sanitizeTextInput } from \"./text-input.js\";\n\n// Utilities\nexport { buildBreadcrumb, buildDetailBreadcrumb } from \"./utils.js\";\nexport { buildFooter, FooterPresets, organizeFooterMessages } from \"./footer-builder.js\";\n\n// For CommonJS compatibility: pre-load ESM dependencies\nlet loadPromise = null;\nexport async function load() {\n    if (loadPromise) return loadPromise;\n    loadPromise = Promise.all([\n        import(\"react\"),\n        import(\"ink\")\n    ]).then(() => {}) ;\n    return loadPromise;\n}\n// Auto-load in ESM, but CJS users should call load() explicitly\nif (typeof window === \"undefined\") {\n    load().catch(() => {\n    // Ignore errors during auto-load, user can call load() explicitly\n    });\n}\n","/**\n * Screen System - Action-based architecture\n */\n\nimport { useState, createElement as h } from \"react\";\nimport { render, useInput, Box, Text } from \"ink\";\nimport chalk from \"chalk\";\nimport { ScreenContainer, ScreenRow, ScreenTitle, ScreenDivider, ScreenFooter, normalizeFooterHotkey } from \"./components.js\";\nimport { MultiColumnListComponent, MultiColumnListWithPreviewComponent, ListComponent } from \"./list-components.js\";\nimport {\n    bindingIdentity,\n    bindingMatchesInput,\n    formatBindingKey,\n} from \"./key-bindings.js\";\nimport { createFlickerFreeStdout } from \"./flicker-free-stdout.js\";\n\n// Types\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Group key bindings by caption for footer display\n */\nexport function groupKeyBindings(bindings) {\n    const groups = {};\n\n    // Filter out disabled bindings\n    const enabledBindings = bindings.filter(b => b.enabled !== false);\n\n    enabledBindings.forEach(binding => {\n        const caption = typeof binding.caption === \"string\" ? binding.caption : \"\";\n        if (!groups[caption]) {\n            groups[caption] = {\n                keys: [],\n                caption: caption,\n                order: binding.order || 999\n            };\n        }\n        groups[caption].keys.push(formatBindingKey(binding));\n        if (binding.kind) groups[caption].kind = binding.kind;\n        if (binding.value !== undefined) groups[caption].value = binding.value;\n        if (binding.valueStyle) groups[caption].valueStyle = binding.valueStyle;\n    });\n\n    return Object.values(groups);\n}\n\n/**\n * Turn key bindings into `{ hotkey, caption }` items for ScreenFooter.\n * Does not style anything — ScreenFooter paints each hotkey.\n *\n * @param {object[]} bindings\n * @param {\"long\"|\"short\"} [mode]\n */\nexport function bindingsToFooterHotkeys(bindings, mode = \"long\") {\n    const customItems = [];\n    const stringBindings = [];\n\n    (bindings || []).forEach((binding) => {\n        if (binding.enabled === false) return;\n        let caption = binding.caption;\n        if (typeof caption === \"function\") {\n            caption = caption();\n        }\n        if (caption != null && typeof caption !== \"string\") {\n            customItems.push({\n                hotkey: [formatBindingKey(binding)],\n                caption: \"\",\n                node: caption,\n                order: binding.order || 999,\n                kind: binding.kind,\n                value: binding.value,\n                valueStyle: binding.valueStyle,\n            });\n            return;\n        }\n        stringBindings.push({ ...binding, caption: caption || \"\" });\n    });\n\n    const groups = groupKeyBindings(stringBindings);\n    groups.sort((a, b) => a.order - b.order);\n\n    const items = groups.map((group) => {\n        const item = {\n            hotkey: group.keys,\n            caption: mode === \"short\" ? \"\" : group.caption,\n            order: group.order,\n        };\n        if (group.kind) item.kind = group.kind;\n        if (group.value !== undefined) item.value = group.value;\n        if (group.valueStyle) item.valueStyle = group.valueStyle;\n        return item;\n    });\n\n    customItems.forEach((item) => items.push(item));\n    items.sort((a, b) => (a.order || 999) - (b.order || 999));\n    return items;\n}\n\n/** @deprecated Use bindingsToFooterHotkeys — returns structured footer items. */\nexport function formatKeyBindings(bindings, mode = \"long\") {\n    return bindingsToFooterHotkeys(bindings, mode);\n}\n\nexport { FOOTER_HOTKEY_STYLE, FOOTER_MUTED_STYLE, normalizeFooterHotkey } from \"./components.js\";\n\n/** Bold default-fg key; `reset` clears a prior dim so later keys stay bright. */\nexport function styleFooterHotkey(label) {\n    return chalk.reset.bold(String(label));\n}\n\n/** Dim caption / separator; `reset` clears bold from the preceding key. */\nexport function styleFooterMuted(text) {\n    return chalk.reset.dim(String(text));\n}\n\n/**\n * One footer binding: highlighted keys, dim \"to …\" caption.\n * Returns a chalk string (not Ink nodes) so every key is independently bright.\n * @param {string} keyStr\n * @param {string} [caption]\n * @param {\"long\"|\"short\"} [mode]\n */\nexport function formatFooterHotkey(keyStr, caption = \"\", mode = \"long\") {\n    const keys = String(keyStr)\n        .split(\"/\")\n        .map((part) => styleFooterHotkey(part))\n        .join(styleFooterMuted(\"/\"));\n    if (mode === \"long\" && caption) {\n        return keys + styleFooterMuted(` to ${caption}`);\n    }\n    return keys;\n}\n\n/**\n * Format keys for display\n */\nexport function formatKeys(keys) {\n    // `keys` may already be display labels (from groupKeyBindings) or raw key names.\n    const keyMap = {\n        escape: \"esc\",\n        leftArrow: \"←\",\n        rightArrow: \"→\",\n        upArrow: \"↑\",\n        downArrow: \"↓\",\n        return: \"enter\",\n        pageUp: \"PgUp\",\n        pageDown: \"PgDn\",\n    };\n\n    return keys.map((k) => keyMap[k] || k).join(\"/\");\n}\n\n/**\n * Show screen with action-based architecture\n */\nexport async function showScreen(config) {\n    const {\n        title,\n        onRender,\n        parentData = {}\n    } = config;\n\n\n    return new Promise((resolve) => {\n        // eslint-disable-next-line prefer-const\n        let instance;\n\n        // Persistent collections (closure variables survive re-renders)\n        const keyBindings = [];\n        const actions = {};\n        const customFooterItems = [];\n        let smartFooterHotkeys = null;\n        let renderResult = null;\n        let initialized = false;\n\n        const Screen = () => {\n            const [, setUpdateCounter] = useState(0);\n\n            // Initialize defaults only once\n            if (!initialized) {\n                const defaultBindings = [\n                    { key: \"escape\", caption: \"go back\", action: \"back\", protected: true, order: 1 },\n                    { key: \"leftArrow\", caption: \"go back\", action: \"back\", protected: false, order: 1 }\n                    // Note: 'select' is not a default - components add it if needed\n                ];\n\n                // Add defaults\n                defaultBindings.forEach(binding => {\n                    keyBindings.push(binding);\n                });\n\n                // Default actions\n                actions.back = () => {\n                    cleanup(null);\n                };\n\n                initialized = true;\n            }\n\n            // Context for onRender\n            const context = {\n                setAction: (actionName, handlerFn) => {\n                    actions[actionName] = handlerFn;\n                },\n\n                setKeyBinding: (bindingOrBindings) => {\n                    // Support both single object and array\n                    const bindingsToSet = Array.isArray(bindingOrBindings) ? bindingOrBindings : [bindingOrBindings];\n\n                    bindingsToSet.forEach(binding => {\n                        const id = bindingIdentity(binding);\n                        const existingIndex = keyBindings.findIndex(\n                            (b) => bindingIdentity(b) === id,\n                        );\n\n                        if (existingIndex >= 0) {\n                            const existing = keyBindings[existingIndex];\n\n                            // Can't override protected keys\n                            if (existing.protected) {\n                                console.warn(`Cannot override protected key: ${binding.key}`);\n                                return;\n                            }\n\n                            // Replace binding (keep original order if not specified)\n                            keyBindings[existingIndex] = {\n                                ...existing,\n                                ...binding,\n                                order: binding.order !== undefined ? binding.order : existing.order,\n                                enabled: binding.enabled !== undefined ? binding.enabled : (existing.enabled !== undefined ? existing.enabled : true)\n                            };\n                        } else {\n                            // Add new binding\n                            keyBindings.push({\n                                protected: false,\n                                order: 999,\n                                enabled: true,\n                                ...binding\n                            });\n                        }\n                    });\n                },\n\n                updateKeyBinding: (keyName, updates) => {\n                    // Prefer identity match when updates carry modifiers; else first key name.\n                    const id =\n                        updates && (updates.meta != null || updates.ctrl != null || updates.shift != null)\n                            ? bindingIdentity({ key: keyName, ...updates })\n                            : null;\n                    const index = keyBindings.findIndex((b) =>\n                        id ? bindingIdentity(b) === id : b.key === keyName,\n                    );\n                    if (index >= 0) {\n                        // Update only specified properties\n                        keyBindings[index] = {\n                            ...keyBindings[index],\n                            ...updates\n                        };\n                    }\n                },\n\n                removeKeyBinding: (keyNameOrBinding) => {\n                    const index =\n                        typeof keyNameOrBinding === \"object\" && keyNameOrBinding\n                            ? keyBindings.findIndex(\n                                  (b) => bindingIdentity(b) === bindingIdentity(keyNameOrBinding),\n                              )\n                            : keyBindings.findIndex((b) => b.key === keyNameOrBinding);\n                    if (index >= 0) {\n                        if (keyBindings[index].protected) {\n                            console.warn(`Cannot remove protected key: ${keyNameOrBinding}`);\n                            return;\n                        }\n                        keyBindings.splice(index, 1);\n                    }\n                },\n\n                addFooter: (item) => {\n                    customFooterItems.push(item);\n                },\n\n                clearFooter: () => {\n                    customFooterItems.length = 0;\n                },\n\n                setFooter: (items) => {\n                    customFooterItems.length = 0;\n                    const itemsArray = Array.isArray(items) ? items : [items];\n                    customFooterItems.push(...itemsArray);\n                },\n\n                /**\n                 * Structured hotkey footer. With no args, rebuild from current\n                 * key bindings. With an array, use those `{ hotkey, caption }`\n                 * items (and optional `kind: \"toggle\", value`) instead.\n                 */\n                setSmartFooter: (items) => {\n                    if (items == null) {\n                        smartFooterHotkeys = null;\n                    } else {\n                        const arr = Array.isArray(items) ? items : [items];\n                        smartFooterHotkeys = arr.map(normalizeFooterHotkey).filter(Boolean);\n                    }\n                },\n\n                update: () => {\n                    setUpdateCounter(c => c + 1);\n                },\n\n                goBack: () => {\n                    if (actions.back) {\n                        actions.back();\n                    }\n                },\n\n                close: (result) => {\n                    cleanup(result);\n                },\n\n                parentData\n            };\n\n            // Call onRender once to let component set up\n            if (!renderResult) {\n                renderResult = onRender(context);\n            }\n\n            // Handle input - dispatch to actions\n            useInput((input, key) => {\n                // Check Ctrl+C for exit\n                if (key.ctrl && input === \"c\") {\n                    cleanup(null);\n                    process.exit(0);\n                    return;\n                }\n\n                // Paste is a multi-char string; Ink leaves only shift/meta/ctrl\n                // on `key`. Do not treat that as a hotkey (`s`, `r`, …).\n                const keyFlags = Object.entries(key || {})\n                    .filter(([, v]) => v === true)\n                    .map(([k]) => k);\n                const pasteLike = keyFlags.every((k) => k === \"shift\" || k === \"meta\" || k === \"ctrl\");\n                if (typeof input === \"string\" && input.length > 1 && pasteLike) {\n                    return;\n                }\n\n                // Find matching key binding\n                let matchedBinding = null;\n\n                for (const binding of keyBindings) {\n                    if (binding.enabled === false) continue;\n                    if (!bindingMatchesInput(binding, input, key)) continue;\n                    if (binding.condition && !binding.condition(context)) continue;\n\n                    matchedBinding = binding;\n                    break;\n                }\n\n                if (matchedBinding && actions[matchedBinding.action]) {\n                    // Execute action\n                    actions[matchedBinding.action]({\n                        input,\n                        key,\n                        binding: matchedBinding\n                    });\n\n                    // If action returns a value, might be used for something\n                    // For now, actions manage their own state via closures\n                }\n            });\n\n            const footerHotkeys = smartFooterHotkeys\n                ?? bindingsToFooterHotkeys(keyBindings, \"long\");\n\n            return h(ScreenContainer, {},\n                h(ScreenTitle, { text: title }),\n                h(ScreenDivider),\n                h(ScreenRow, {}, h(Text, {}, \" \")),\n                renderResult,\n                h(ScreenRow, {}, h(Text, {}, \" \")),\n                h(ScreenDivider),\n                h(ScreenFooter, {\n                    hotkeys: footerHotkeys,\n                    lines: customFooterItems,\n                })\n            );\n        };\n\n        const cleanup = (result) => {\n            if (instance) instance.unmount();\n            setTimeout(() => resolve(result), 50);\n        };\n\n        instance = render(h(Screen), {\n            patchConsole: false,\n            stdout: createFlickerFreeStdout(process.stdout),\n        });\n    });\n}\n\n/**\n * Helper: Show list screen (single column menu)\n */\nexport async function showListScreen(config) {\n    const { title, items, onSelect, onEscape, parentData, initialSelectedIndex = 0, renderItem, getTitle, sortable, maxHeight, sortHighlightStyle, selectionMarker } = config;\n\n    return showScreen({\n        title,\n        parentData,\n        onRender: (ctx) => {\n            // Shared state ref\n            const selectedIndexRef = { current: initialSelectedIndex };\n\n            // Set up select action at screen level\n            ctx.setAction(\"select\", () => {\n                const selected = items[selectedIndexRef.current];\n                if (onSelect) {\n                    const result = onSelect(selected.value, selectedIndexRef.current);\n                    ctx.close(result);\n                }\n            });\n\n            // Set up back action if provided\n            if (onEscape) {\n                ctx.setAction(\"back\", () => {\n                    const result = onEscape(selectedIndexRef.current);\n                    ctx.close(result);\n                });\n            }\n\n            // Add select key binding\n            ctx.setKeyBinding({ key: \"return\", caption: \"select\", action: \"select\", order: 2 });\n\n            // Return the component (it will set up its own navigation actions and bindings)\n            return h(ListComponent, { items, ctx, selectedIndexRef, renderItem, getTitle, sortable, maxHeight, sortHighlightStyle, selectionMarker });\n        }\n    });\n}\n\n/**\n * Helper: Show multi-column list screen (grid layout)\n */\nexport async function showMultiColumnListScreen(config) {\n    const { title, items, onSelect, onEscape, parentData, initialSelectedIndex = 0 } = config;\n\n    return showScreen({\n        title,\n        parentData,\n        onRender: (ctx) => {\n            // Shared state ref\n            const selectedIndexRef = { current: initialSelectedIndex };\n\n            // Set up select action at screen level\n            ctx.setAction(\"select\", () => {\n                const selected = items[selectedIndexRef.current];\n                if (onSelect) {\n                    const result = onSelect(selected, selectedIndexRef.current);\n                    ctx.close(result);\n                }\n            });\n\n            // Set up back action if provided\n            if (onEscape) {\n                ctx.setAction(\"back\", () => {\n                    const result = onEscape(selectedIndexRef.current);\n                    ctx.close(result);\n                });\n            }\n\n            // Add select key binding\n            ctx.setKeyBinding({ key: \"return\", caption: \"select\", action: \"select\", order: 2 });\n\n            // Return the component (it will set up its own navigation actions and bindings)\n            return h(MultiColumnListComponent, { items, ctx, selectedIndexRef });\n        }\n    });\n}\n\n/**\n * Helper: Show multi-column list with preview panel below\n */\nexport async function showMultiColumnListWithPreviewScreen(config) {\n    const { title, items, getPreviewContent, onSelect, onEscape, parentData, initialSelectedIndex = 0 } = config;\n\n    return showScreen({\n        title,\n        parentData,\n        onRender: (ctx) => {\n            // Shared state ref\n            const selectedIndexRef = { current: initialSelectedIndex };\n\n            // Set up select action at screen level\n            ctx.setAction(\"select\", () => {\n                const selected = items[selectedIndexRef.current];\n                if (onSelect) {\n                    const result = onSelect(selected, selectedIndexRef.current);\n                    ctx.close(result);\n                }\n            });\n\n            // Set up back action if provided\n            if (onEscape) {\n                ctx.setAction(\"back\", () => {\n                    const result = onEscape(selectedIndexRef.current);\n                    ctx.close(result);\n                });\n            }\n\n            // Add select key binding\n            ctx.setKeyBinding({ key: \"return\", caption: \"select\", action: \"select\", order: 2 });\n\n            // Return the component (it will set up its own navigation actions and bindings)\n            return h(MultiColumnListWithPreviewComponent, { items, getPreviewContent, ctx, selectedIndexRef });\n        }\n    });\n}\n\n// Backward compatibility aliases\nexport const showMenuScreen = showListScreen;\nexport const showWordGridScreen = showMultiColumnListScreen;\n","/**\n * Core screen layout components\n */\n\nimport React, { createElement as h } from \"react\";\nimport { Box, Text } from \"ink\";\nimport { getScreenFrameBoxHeight } from \"./screen-layout.js\";\nimport { stripAnsi } from \"./visible-text.js\";\n\n/**\n * Get screen width for borders\n * @param maxWidth - Optional max width (null = no limit)\n */\nexport function getScreenWidth(maxWidth = null) {\n    const terminalWidth = process.stdout.columns || 80;\n    // Leave some margin for borders and padding\n    const availableWidth = Math.max(20, terminalWidth - 4);\n    return maxWidth ? Math.min(availableWidth, maxWidth) : availableWidth;\n}\n\n// Types\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Screen Container - uses Ink's built-in borderStyle for proper text wrapping\n */\nexport function ScreenContainer({ children }) {\n    const width = getScreenWidth();\n    const maxHeight = getScreenFrameBoxHeight();\n\n    return h(Box, {\n        flexDirection: \"column\",\n        marginTop: 1,\n        borderStyle: \"single\",\n        borderColor: \"cyan\",\n        paddingX: 1,\n        width,\n        maxHeight,\n        overflow: \"hidden\",\n    }, children);\n}\n\n/**\n * Screen row - just a wrapper for spacing, borders handled by container\n */\nexport function ScreenRow({ children, ...boxProps }) {\n    return h(Box, { flexDirection: \"column\", ...boxProps }, children);\n}\n\n/**\n * Screen Title - first line inside container (left-aligned, breadcrumb-style)\n */\nexport function ScreenTitle({ text }) {\n    return h(ScreenRow, { flexShrink: 0 },\n        h(Text, { bold: true, color: \"cyan\", wrap: \"truncate\" }, text)\n    );\n}\n\n/**\n * Horizontal divider line\n */\nexport function ScreenDivider({ width }) {\n    const dividerWidth = width || (getScreenWidth() - 4); // Account for border and padding\n    return h(Text, { color: \"cyan\", dimColor: true }, \"─\".repeat(dividerWidth));\n}\n\n/**\n * Screen Body - main content area\n */\nexport function ScreenBody({ children, alignItems = \"flex-start\" }) {\n    return h(Box, { flexDirection: \"column\", alignItems }, children);\n}\n\n/** Bold key label. Do not use dimColor here — dim and bold share SGR 22. */\nexport const FOOTER_HOTKEY_STYLE = { bold: true };\n\n/** Caption / separator. Gray, not dim, so later keys stay bold. */\nexport const FOOTER_MUTED_STYLE = { color: \"gray\" };\n\n/**\n * Normalize one footer item: `{ hotkey, caption }` (aliases: key, title, text).\n * `hotkey` may be a string (`\"esc/←\"`) or an array of labels.\n */\nexport function normalizeFooterHotkey(item) {\n    if (item == null) return null;\n    if (typeof item === \"string\") {\n        return { hotkey: [item], caption: \"\" };\n    }\n    const raw = item.hotkey ?? item.key;\n    const hotkey = Array.isArray(raw)\n        ? raw.map(String)\n        : String(raw ?? \"\").split(\"/\").map((s) => s.trim()).filter(Boolean);\n    return {\n        ...item,\n        hotkey,\n        caption: item.caption ?? item.title ?? item.text ?? \"\",\n    };\n}\n\nfunction renderHotkeyPieces(item, reactKey) {\n    const normalized = normalizeFooterHotkey(item);\n    if (!normalized) return [];\n    if (normalized.node && React.isValidElement(normalized.node)) {\n        return [\n            normalized.node.key == null\n                ? React.cloneElement(normalized.node, { key: reactKey })\n                : normalized.node,\n        ];\n    }\n\n    const pieces = [];\n    normalized.hotkey.forEach((label, i) => {\n        if (i > 0) {\n            pieces.push(h(Text, { key: `${reactKey}-sep${i}`, ...FOOTER_MUTED_STYLE }, \"/\"));\n        }\n        pieces.push(h(Text, { key: `${reactKey}-k${i}`, ...FOOTER_HOTKEY_STYLE }, label));\n    });\n\n    if (normalized.caption) {\n        pieces.push(h(Text, { key: `${reactKey}-cap`, ...FOOTER_MUTED_STYLE }, ` to ${normalized.caption}`));\n    }\n\n    if (normalized.kind === \"toggle\" && normalized.value) {\n        pieces.push(h(Text, { key: `${reactKey}-sp`, ...FOOTER_MUTED_STYLE }, \" \"));\n        pieces.push(h(\n            Text,\n            { key: `${reactKey}-val`, ...(normalized.valueStyle || FOOTER_HOTKEY_STYLE) },\n            ` ${normalized.value} `,\n        ));\n    }\n\n    return pieces;\n}\n\n/**\n * Screen Footer — hotkeys are structured items, styled here (not parsed from a string).\n *\n * @example\n * <ScreenFooter hotkeys={[\n *   { hotkey: [\"esc\", \"←\"], caption: \"go back\" },\n *   { hotkey: \"enter\", caption: \"select\" },\n *   { hotkey: \"s\", caption: \"sort\", kind: \"toggle\", value: \"ASC\" },\n * ]} />\n *\n * Extra status lines (not hotkeys) still go in `lines`.\n */\nexport function ScreenFooter({ hotkeys, lines, textStyle }) {\n    const defaultTextStyle = {\n        dimColor: true,\n        color: \"white\"\n    };\n    \n    const finalTextStyle = { ...defaultTextStyle, ...textStyle };\n\n    const flattenAndWrap = (items, keyPrefix = \"\") => {\n        const result = [];\n        let keyIndex = 0;\n\n        (items || []).forEach((item, index) => {\n            if (Array.isArray(item)) {\n                const nested = flattenAndWrap(item, `${keyPrefix}-${index}`);\n                result.push(...nested);\n            } else if (typeof item === \"string\") {\n                const preStyled = stripAnsi(item) !== item;\n                result.push(\n                    h(Text, {\n                        key: `${keyPrefix}-${keyIndex++}`,\n                        ...(preStyled ? {} : finalTextStyle),\n                    }, item)\n                );\n            } else if (React.isValidElement(item)) {\n                result.push(\n                    item.key == null\n                        ? React.cloneElement(item, { key: `${keyPrefix}-${keyIndex++}` })\n                        : item\n                );\n            } else if (item != null) {\n                result.push(item);\n            }\n        });\n\n        return result;\n    };\n\n    const hotkeyPieces = [];\n    (hotkeys || []).forEach((item, idx) => {\n        if (idx > 0) {\n            hotkeyPieces.push(h(Text, { key: `hk-join-${idx}`, ...FOOTER_MUTED_STYLE }, \", \"));\n        }\n        hotkeyPieces.push(...renderHotkeyPieces(item, `hk-${idx}`));\n    });\n\n    const extraRows = (lines && lines.length)\n        ? flattenAndWrap(lines, \"line\")\n        : [];\n\n    const rows = [];\n    if (hotkeyPieces.length) {\n        rows.push(h(Box, { key: \"hotkeys\", flexDirection: \"row\" }, ...hotkeyPieces));\n    }\n    if (extraRows.length) {\n        rows.push(h(Box, { key: \"lines\", flexDirection: \"row\" }, ...extraRows));\n    }\n\n    return h(Box, { flexDirection: \"column\" }, ...rows);\n}","/**\n * showScreen chrome (must match screens.js + ScreenContainer):\n *   1 marginTop\n *   1 border top + 1 border bottom\n *   1 title\n *   1 divider\n *   1 blank spacer\n *   1 blank spacer\n *   1 divider\n *   N footer lines (default 1)\n *\n * Ink’s log-update does clearTerminal when outputHeight >= stdout.rows.\n * That wipe is the “everything flickers, title scrolled off” failure mode.\n * Keep one unused row so the frame always fits.\n */\n\nexport const SCREEN_MARGIN_TOP = 1;\nexport const SCREEN_CHROME_WITHOUT_FOOTER = 8;\nexport const INK_HEIGHT_SLACK = 1;\n\nexport function getScreenChromeRows({ footerLines = 1 } = {}) {\n    return SCREEN_CHROME_WITHOUT_FOOTER + Math.max(0, Number(footerLines) || 0);\n}\n\n/**\n * Rows left for a scroll viewport (log lines, list rows) after chrome +\n * any extra header/status lines the body renders.\n */\nexport function getScreenBodyRows({\n    extraRows = 0,\n    footerLines = 1,\n    minRows = 4,\n    termRows = process.stdout.rows || 24,\n} = {}) {\n    const rows = Number(termRows) || 24;\n    const reserved =\n        getScreenChromeRows({ footerLines }) +\n        Math.max(0, Number(extraRows) || 0) +\n        INK_HEIGHT_SLACK;\n    return Math.max(minRows, rows - reserved);\n}\n\n/**\n * ScreenContainer Box maxHeight (margin is outside). margin + this <= termRows - slack.\n */\nexport function getScreenFrameBoxHeight({ termRows = process.stdout.rows || 24 } = {}) {\n    const rows = Number(termRows) || 24;\n    return Math.max(8, rows - SCREEN_MARGIN_TOP - INK_HEIGHT_SLACK);\n}\n","/**\n * Terminal-visible width: ignore ANSI, count code points as one cell.\n * Keeps scrollbar / pad math aligned when log lines carry chalk codes.\n */\n\nconst ANSI_RE = /\\u001b(?:[@-Z\\\\-_]|\\[[0-?]*[ -/]*[@-~])/g;\n\nexport function stripAnsi(text) {\n    return String(text ?? \"\").replace(ANSI_RE, \"\");\n}\n\nexport function visibleWidth(text) {\n    return [...stripAnsi(text)].length;\n}\n\n/**\n * First `cols` visible cells, preserving ANSI in that span.\n */\nexport function sliceVisible(text, cols) {\n    const w = Math.max(0, Math.floor(Number(cols) || 0));\n    const s = String(text ?? \"\");\n    if (w === 0) return \"\";\n    let vis = 0;\n    let out = \"\";\n    let i = 0;\n    while (i < s.length && vis < w) {\n        ANSI_RE.lastIndex = i;\n        const m = ANSI_RE.exec(s);\n        if (m && m.index === i) {\n            out += m[0];\n            i += m[0].length;\n            continue;\n        }\n        const cp = s.codePointAt(i);\n        const ch = String.fromCodePoint(cp);\n        out += ch;\n        i += ch.length;\n        vis += 1;\n    }\n    return out;\n}\n\nexport function padEndVisible(text, cols) {\n    const w = Math.max(0, Math.floor(Number(cols) || 0));\n    const s = String(text ?? \"\");\n    const vis = visibleWidth(s);\n    if (vis === w) return s;\n    if (vis > w) return sliceVisible(s, w);\n    return s + \" \".repeat(w - vis);\n}\n\n/**\n * Hard-wrap on visible columns (keeps empty lines). ANSI stays with its text.\n */\nexport function wrapTextLines(text, cols) {\n    const w = Math.max(1, Math.floor(Number(cols) || 1));\n    const out = [];\n    for (const raw of String(text ?? \"\").split(\"\\n\")) {\n        if (raw.length === 0) {\n            out.push(\"\");\n            continue;\n        }\n        if (visibleWidth(raw) <= w) {\n            out.push(raw);\n            continue;\n        }\n        let rest = raw;\n        while (visibleWidth(rest) > w) {\n            const head = sliceVisible(rest, w);\n            out.push(head);\n            rest = rest.slice(head.length);\n        }\n        if (rest.length > 0) out.push(rest);\n    }\n    return out;\n}\n","/**\n * Reusable screen components for V2 architecture\n */\n\nimport React, { useState, useEffect, useRef, createElement } from \"react\";\nimport { Box, Text } from \"ink\";\nimport { ScreenRow, ScreenDivider } from \"./components.js\";\nimport {\n    BAR_THUMB,\n    BAR_TRACK,\n    PAGE_SCROLL_KEY_BINDINGS,\n    scrollbarGlyphs,\n} from \"./scrollbar.js\";\n\nconst h = createElement;\n\n/**\n * Make room for a 1-cell scrollbar. Full-width table rows are padEnd'd (trailing\n * space) — trim one cell. Short labels are left alone (bar just appends).\n */\nfunction clipNameForScrollbar(name, needsBar) {\n    if (!needsBar || name == null) return name;\n    const s = String(name);\n    if (s.length <= 1) return s;\n    if (/\\s$/.test(s)) return s.slice(0, -1);\n    return s;\n}\n\n// TODO: Define proper context type interface\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Multi-column list component\n * Handles its own navigation, actions, and key bindings\n */\nexport function MultiColumnListComponent({ items, ctx, selectedIndexRef }) {\n    const [, forceUpdate] = useState({});\n\n    // Calculate layout\n    const termWidth = (process.stdout.columns || 80) - 8;\n    const maxItemLength = Math.max(...items.map(w => w.length));\n    const columnWidth = maxItemLength + 3;\n    const columns = Math.max(1, Math.floor(termWidth / columnWidth));\n    const itemsPerColumn = Math.ceil(items.length / columns);\n\n    // Set up actions in useEffect (runs once)\n    useEffect(() => {\n        ctx.setAction(\"moveUp\", () => {\n            selectedIndexRef.current = Math.max(0, selectedIndexRef.current - 1);\n            forceUpdate({});\n        });\n\n        ctx.setAction(\"moveDown\", () => {\n            selectedIndexRef.current = Math.min(items.length - 1, selectedIndexRef.current + 1);\n            forceUpdate({});\n        });\n\n        ctx.setAction(\"moveLeft\", () => {\n            if (selectedIndexRef.current === 0) {\n                ctx.goBack();\n            } else {\n                selectedIndexRef.current = Math.max(0, selectedIndexRef.current - itemsPerColumn);\n                forceUpdate({});\n            }\n        });\n\n        ctx.setAction(\"moveRight\", () => {\n            selectedIndexRef.current = Math.min(items.length - 1, selectedIndexRef.current + itemsPerColumn);\n            forceUpdate({});\n        });\n\n        // Set up key bindings\n        ctx.setKeyBinding([\n            { key: \"leftArrow\", caption: \"navigate\", action: \"moveLeft\", order: 0 },\n            { key: \"rightArrow\", caption: \"navigate\", action: \"moveRight\", order: 0 },\n            { key: \"upArrow\", caption: \"navigate\", action: \"moveUp\", order: 0 },\n            { key: \"downArrow\", caption: \"navigate\", action: \"moveDown\", order: 0 }\n        ]);\n\n        // Add footer\n        ctx.addFooter(`Total: ${items.length} items`);\n    }, []);\n\n    const selectedIndex = selectedIndexRef.current;\n\n    // Build grid\n    const rows = [];\n    for (let row = 0; row < itemsPerColumn; row++) {\n        const cols = [];\n        for (let col = 0; col < columns; col++) {\n            const index = col * itemsPerColumn + row;\n            if (index < items.length) {\n                const isSelected = index === selectedIndex;\n                cols.push(\n                    h(Box, { key: index, width: columnWidth },\n                        h(Text, {\n                            color: isSelected ? \"black\" : \"white\",\n                            backgroundColor: isSelected ? \"cyan\" : undefined,\n                            bold: isSelected\n                        }, items[index].padEnd(maxItemLength))\n                    )\n                );\n            }\n        }\n        rows.push(\n            h(ScreenRow, { key: row, children: h(Box, { flexDirection: \"row\" }, ...cols) })\n        );\n    }\n\n    return h(Box, { flexDirection: \"column\" }, ...rows);\n}\n\n/**\n * Multi-column list with preview panel component\n * Shows selected item details below the list\n */\nexport function MultiColumnListWithPreviewComponent({\n    items,\n    getPreviewContent,\n    ctx,\n    selectedIndexRef\n}) {\n    const [, forceUpdate] = useState({});\n\n    // Calculate layout\n    const termWidth = (process.stdout.columns || 80) - 8;\n    const maxItemLength = Math.max(...items.map(w => w.length));\n    const columnWidth = maxItemLength + 3;\n    const columns = Math.max(1, Math.floor(termWidth / columnWidth));\n    const itemsPerColumn = Math.ceil(items.length / columns);\n\n    // Set up actions in useEffect (runs once)\n    useEffect(() => {\n        ctx.setAction(\"moveUp\", () => {\n            selectedIndexRef.current = Math.max(0, selectedIndexRef.current - 1);\n            forceUpdate({});\n        });\n\n        ctx.setAction(\"moveDown\", () => {\n            selectedIndexRef.current = Math.min(items.length - 1, selectedIndexRef.current + 1);\n            forceUpdate({});\n        });\n\n        ctx.setAction(\"moveLeft\", () => {\n            if (selectedIndexRef.current === 0) {\n                ctx.goBack();\n            } else {\n                selectedIndexRef.current = Math.max(0, selectedIndexRef.current - itemsPerColumn);\n                forceUpdate({});\n            }\n        });\n\n        ctx.setAction(\"moveRight\", () => {\n            selectedIndexRef.current = Math.min(items.length - 1, selectedIndexRef.current + itemsPerColumn);\n            forceUpdate({});\n        });\n\n        // Set up key bindings\n        ctx.setKeyBinding([\n            { key: \"leftArrow\", caption: \"navigate\", action: \"moveLeft\", order: 0 },\n            { key: \"rightArrow\", caption: \"navigate\", action: \"moveRight\", order: 0 },\n            { key: \"upArrow\", caption: \"navigate\", action: \"moveUp\", order: 0 },\n            { key: \"downArrow\", caption: \"navigate\", action: \"moveDown\", order: 0 }\n        ]);\n\n        // Add footer\n        ctx.addFooter(`Total: ${items.length} items`);\n    }, []);\n\n    const selectedIndex = selectedIndexRef.current;\n    const selectedItem = items[selectedIndex];\n\n    // Build grid\n    const rows = [];\n    for (let row = 0; row < itemsPerColumn; row++) {\n        const cols = [];\n        for (let col = 0; col < columns; col++) {\n            const index = col * itemsPerColumn + row;\n            if (index < items.length) {\n                const isSelected = index === selectedIndex;\n                cols.push(\n                    h(Box, { key: index, width: columnWidth },\n                        h(Text, {\n                            color: isSelected ? \"black\" : \"white\",\n                            backgroundColor: isSelected ? \"cyan\" : undefined,\n                            bold: isSelected\n                        }, items[index].padEnd(maxItemLength))\n                    )\n                );\n            }\n        }\n        rows.push(\n            h(ScreenRow, { key: row, children: h(Box, { flexDirection: \"row\" }, ...cols) })\n        );\n    }\n\n    // Get preview content for selected item\n    const previewContent = getPreviewContent ? getPreviewContent(selectedItem) : selectedItem;\n\n    const previewRows = [];\n    if (typeof previewContent === \"string\") {\n        previewRows.push(h(ScreenRow, { key: \"preview-string\", children: h(Text, { bold: true }, previewContent) }));\n    } else if (typeof previewContent === \"object\" && !React.isValidElement(previewContent) && previewContent !== null) {\n        Object.entries(previewContent).forEach(([key, value], idx) => {\n            previewRows.push(h(ScreenRow, { key: `preview-${key}-${idx}`, children: h(Text, {}, `${key}: ${value}`) }));\n        });\n    } else if (React.isValidElement(previewContent)) {\n        previewRows.push(h(ScreenRow, { key: \"preview-element\", children: previewContent }));\n    }\n\n    return h(Box, { flexDirection: \"column\" },\n        ...rows,\n        h(ScreenRow, { key: \"spacer-1\", children: h(Text, {}, \" \") }),\n        h(ScreenDivider, { key: \"divider\" }),\n        h(ScreenRow, { key: \"spacer-2\", children: h(Text, {}, \" \") }),\n        ...previewRows\n    );\n}\n\n/**\n * Single-column list component\n * Simple vertical menu with optional sorting\n */\nexport function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sortable = false, maxHeight, sortHighlightStyle, selectionMarker = \" \", onSelectionChange }) {\n    const [, forceUpdate] = useState({});\n    const [sortOrder, setSortOrder] = useState(\"none\");\n    const [scrollOffset, setScrollOffset] = useState(0);\n    \n    // Use refs to store current scroll values to avoid stale closures\n    const scrollStateRef = useRef({ scrollOffset: 0, maxHeight: 0, totalItems: 0 });\n    const itemsRef = useRef(items);\n    itemsRef.current = items;\n\n    // Default getTitle - returns item if string, otherwise item.title\n    const defaultGetTitle = (item) => {\n        return getTitle ? getTitle(item) : (typeof item.value === \"string\" ? item.value : (item.value?.title || item.name));\n    };\n\n    // Get title for sorting\n    const titleGetter = getTitle || defaultGetTitle;\n\n    // Apply sorting if enabled\n    const displayItems = sortable && sortOrder !== \"none\" ? [...items].sort((a, b) => {\n        const titleA = titleGetter(a).toLowerCase();\n        const titleB = titleGetter(b).toLowerCase();\n        if (sortOrder === \"asc\") {\n            return titleA < titleB ? -1 : titleA > titleB ? 1 : 0;\n        } else {\n            return titleA > titleB ? -1 : titleA < titleB ? 1 : 0;\n        }\n    }) : items;\n\n    const displayItemsRef = useRef(displayItems);\n    displayItemsRef.current = displayItems;\n\n    // Calculate scrolling\n    const effectiveMaxHeight = maxHeight || displayItems.length;\n    const _canScroll = displayItems.length > effectiveMaxHeight;\n    const maxScrollOffset = Math.max(0, displayItems.length - effectiveMaxHeight);\n    \n    // Ensure scroll offset is within bounds\n    const clampedScrollOffset = Math.min(Math.max(0, scrollOffset), maxScrollOffset);\n    \n    // Get visible items\n    const visibleItems = displayItems.slice(clampedScrollOffset, clampedScrollOffset + effectiveMaxHeight);\n    \n    // Check if we can scroll up/down\n    const canScrollUp = clampedScrollOffset > 0;\n    const canScrollDown = clampedScrollOffset < maxScrollOffset;\n    \n    // Update scroll state ref with current values\n    scrollStateRef.current = { scrollOffset, maxHeight: effectiveMaxHeight, totalItems: displayItems.length };\n    \n\n    const onSelectionChangeRef = useRef(onSelectionChange);\n    onSelectionChangeRef.current = onSelectionChange;\n\n    // Set up actions in useEffect (runs once)\n    useEffect(() => {\n        ctx.setAction(\"moveUp\", () => {\n            const newIndex = Math.max(0, selectedIndexRef.current - 1);\n            selectedIndexRef.current = newIndex;\n            const list = displayItemsRef.current;\n            onSelectionChangeRef.current?.(newIndex, list[newIndex]);\n\n            // Auto-scroll to keep selected item visible\n            const { scrollOffset: currentScrollOffset, maxHeight: currentMaxHeight, totalItems } = scrollStateRef.current;\n            const currentMaxScrollOffset = Math.max(0, totalItems - currentMaxHeight);\n            const currentClampedScrollOffset = Math.min(Math.max(0, currentScrollOffset), currentMaxScrollOffset);\n\n            if (newIndex < currentClampedScrollOffset) {\n                setScrollOffset(newIndex);\n            }\n\n            forceUpdate({});\n        });\n\n        ctx.setAction(\"moveDown\", () => {\n            const currentItems = displayItemsRef.current;\n            const maxIndex = Math.max(0, currentItems.length - 1);\n            const newIndex = Math.min(maxIndex, selectedIndexRef.current + 1);\n            selectedIndexRef.current = newIndex;\n            onSelectionChangeRef.current?.(newIndex, currentItems[newIndex]);\n\n            // Auto-scroll to keep selected item visible\n            const { scrollOffset: currentScrollOffset, maxHeight: currentMaxHeight, totalItems } = scrollStateRef.current;\n            const currentMaxScrollOffset = Math.max(0, totalItems - currentMaxHeight);\n            const currentClampedScrollOffset = Math.min(Math.max(0, currentScrollOffset), currentMaxScrollOffset);\n\n            if (newIndex >= currentClampedScrollOffset + currentMaxHeight) {\n                setScrollOffset(newIndex - currentMaxHeight + 1);\n            }\n\n            forceUpdate({});\n        });\n\n        // Viewport scroll (without moving selection)\n        ctx.setAction(\"scrollUp\", () => {\n            const { scrollOffset: currentScrollOffset } = scrollStateRef.current;\n            setScrollOffset(Math.max(0, currentScrollOffset - 1));\n            forceUpdate({});\n        });\n\n        ctx.setAction(\"scrollDown\", () => {\n            const { scrollOffset: currentScrollOffset, maxHeight: currentMaxHeight, totalItems } =\n                scrollStateRef.current;\n            const currentMaxScrollOffset = Math.max(0, totalItems - currentMaxHeight);\n            setScrollOffset(Math.min(currentMaxScrollOffset, currentScrollOffset + 1));\n            forceUpdate({});\n        });\n\n        // Page: move selection by one viewport, keep it visible (⌥/Ctrl+↑↓, PgUp/PgDn)\n        ctx.setAction(\"pageUp\", () => {\n            const { maxHeight: vh } = scrollStateRef.current;\n            const page = Math.max(1, vh || 1);\n            const newIndex = Math.max(0, selectedIndexRef.current - page);\n            selectedIndexRef.current = newIndex;\n            const list = displayItemsRef.current;\n            onSelectionChangeRef.current?.(newIndex, list[newIndex]);\n            setScrollOffset(newIndex);\n            forceUpdate({});\n        });\n\n        ctx.setAction(\"pageDown\", () => {\n            const { maxHeight: vh, totalItems } = scrollStateRef.current;\n            const page = Math.max(1, vh || 1);\n            const maxIndex = Math.max(0, totalItems - 1);\n            const newIndex = Math.min(maxIndex, selectedIndexRef.current + page);\n            selectedIndexRef.current = newIndex;\n            const list = displayItemsRef.current;\n            onSelectionChangeRef.current?.(newIndex, list[newIndex]);\n            const maxScroll = Math.max(0, totalItems - page);\n            setScrollOffset(Math.min(maxScroll, Math.max(0, newIndex - page + 1)));\n            forceUpdate({});\n        });\n\n        const navBindings = [\n            { key: \"upArrow\", caption: \"navigate\", action: \"moveUp\", order: 0 },\n            { key: \"downArrow\", caption: \"navigate\", action: \"moveDown\", order: 0 },\n            ...PAGE_SCROLL_KEY_BINDINGS,\n        ];\n\n        // Set up sort action if sortable\n        if (sortable) {\n            ctx.setAction(\"toggleSort\", () => {\n                const nextSort = \n                    sortOrder === \"none\" ? \"asc\" : \n                        sortOrder === \"asc\" ? \"desc\" : \"none\";\n                \n                // Store the currently selected item from the current display items\n                const currentSelectedItem = displayItemsRef.current[selectedIndexRef.current];\n                \n                setSortOrder(nextSort);\n                \n                // Calculate the new sorted items\n                const newSortedItems = nextSort !== \"none\" ? [...itemsRef.current].sort((a, b) => {\n                    const titleA = titleGetter(a).toLowerCase();\n                    const titleB = titleGetter(b).toLowerCase();\n                    if (nextSort === \"asc\") {\n                        return titleA < titleB ? -1 : titleA > titleB ? 1 : 0;\n                    } else {\n                        return titleA > titleB ? -1 : titleA < titleB ? 1 : 0;\n                    }\n                }) : itemsRef.current;\n                \n                // Find the new index of the selected item in the new sorted list\n                const newIndex = newSortedItems.findIndex(item => item === currentSelectedItem);\n                if (newIndex !== -1) {\n                    selectedIndexRef.current = newIndex;\n                    // Set scroll position to show the selected item at the top\n                    setScrollOffset(newIndex);\n                } else {\n                    // Fallback: if item not found, select first item\n                    selectedIndexRef.current = 0;\n                    setScrollOffset(0);\n                }\n                \n                forceUpdate({});\n            });\n\n            // Default highlight style (green background, black text, bold)\n            const defaultHighlightStyle = {\n                color: \"black\",\n                backgroundColor: \"green\", \n                bold: true\n            };\n            const highlightStyle = { ...defaultHighlightStyle, ...sortHighlightStyle };\n\n            ctx.setKeyBinding([\n                ...navBindings,\n                {\n                    key: \"s\",\n                    caption: \"toggle sort\",\n                    action: \"toggleSort\",\n                    order: 5,\n                    kind: \"toggle\",\n                    value: sortOrder === \"none\" ? undefined : sortOrder === \"asc\" ? \"ASC\" : \"DESC\",\n                    valueStyle: highlightStyle,\n                },\n            ]);\n\n            // Force update to show the new caption in footer\n            ctx.update();\n        } else {\n            ctx.setKeyBinding(navBindings);\n        }\n    }, [sortOrder, sortable]);\n\n    const selectedIndex = selectedIndexRef.current;\n    const needsBar = displayItems.length > effectiveMaxHeight;\n    const barGlyphs = needsBar\n        ? scrollbarGlyphs(effectiveMaxHeight, displayItems.length, clampedScrollOffset)\n        : null;\n\n    const appendBar = (rowContent, displayIndex) => {\n        if (!barGlyphs) return rowContent;\n        const glyph = barGlyphs[displayIndex] ?? BAR_TRACK;\n        return h(\n            Box,\n            { flexDirection: \"row\" },\n            rowContent,\n            h(Text, { color: glyph === BAR_THUMB ? \"cyan\" : \"gray\" }, glyph),\n        );\n    };\n\n    // Default renderer — edge ↑/↓ only when there is no scrollbar (bar replaces them).\n    const defaultRenderItem = (item, isSelected, displayIndex, actualIndex) => {\n        const isFirstVisible = displayIndex === 0;\n        const isLastVisible = displayIndex === visibleItems.length - 1;\n\n        let arrowPrefix = \"  \";\n        if (!needsBar) {\n            if (isFirstVisible && canScrollUp) arrowPrefix = \"↑ \";\n            else if (isLastVisible && canScrollDown) arrowPrefix = \"↓ \";\n        }\n\n        const selectionPrefix = isSelected\n            ? selectionMarker\n            : \" \".repeat(selectionMarker.length);\n\n        const label = clipNameForScrollbar(item.name, needsBar);\n\n        return h(\n            Box,\n            { flexDirection: \"row\" },\n            h(Text, { key: \"arrow\", color: \"white\" }, arrowPrefix),\n            h(Text, { key: \"marker\", color: \"white\" }, selectionPrefix),\n            h(\n                Text,\n                {\n                    key: \"name\",\n                    color: isSelected ? \"black\" : \"white\",\n                    backgroundColor: isSelected ? \"cyan\" : undefined,\n                    bold: isSelected,\n                },\n                label,\n            ),\n        );\n    };\n\n    const itemRenderer = renderItem || defaultRenderItem;\n\n    return h(\n        Box,\n        { flexDirection: \"column\" },\n        ...visibleItems.map((item, displayIndex) => {\n            const actualIndex = clampedScrollOffset + displayIndex;\n            const isSelected = actualIndex === selectedIndex;\n\n            if (renderItem) {\n                const isFirstVisible = displayIndex === 0;\n                const isLastVisible = displayIndex === visibleItems.length - 1;\n\n                let arrowPrefix = \"  \";\n                if (!needsBar) {\n                    if (isFirstVisible && canScrollUp) arrowPrefix = \"↑ \";\n                    else if (isLastVisible && canScrollDown) arrowPrefix = \"↓ \";\n                }\n\n                const selectionPrefix = isSelected\n                    ? selectionMarker\n                    : \" \".repeat(selectionMarker.length);\n\n                const clipped = needsBar\n                    ? { ...item, name: clipNameForScrollbar(item.name, true) }\n                    : item;\n\n                const row = h(\n                    Box,\n                    { flexDirection: \"row\" },\n                    h(Text, { key: \"arrow\", color: \"white\" }, arrowPrefix),\n                    h(Text, { key: \"marker\", color: \"white\" }, selectionPrefix),\n                    renderItem(clipped, isSelected, displayIndex),\n                );\n\n                return h(ScreenRow, {\n                    key: `slot-${displayIndex}`,\n                    children: appendBar(row, displayIndex),\n                });\n            }\n\n            return h(ScreenRow, {\n                key: `slot-${displayIndex}`,\n                children: appendBar(\n                    itemRenderer(item, isSelected, displayIndex, actualIndex),\n                    displayIndex,\n                ),\n            });\n        }),\n    );\n}\n","/**\n * Shared proportional scrollbar (ASCII — block glyphs are often double-width).\n */\n\nexport const BAR_THUMB = \"#\";\nexport const BAR_TRACK = \"|\";\n\n/**\n * Proportional scrollbar glyphs for a viewport.\n * @returns {string[]|null} one glyph per viewport row, or null when no overflow\n */\nexport function scrollbarGlyphs(viewportRows, totalLines, scrollTop) {\n    const view = Math.max(1, Math.floor(viewportRows));\n    const total = Math.max(0, Math.floor(totalLines));\n    if (total <= view) return null;\n\n    const maxScroll = total - view;\n    const thumbSize = Math.max(1, Math.round((view / total) * view));\n    const travel = Math.max(0, view - thumbSize);\n    const s = Math.min(Math.max(0, Math.floor(scrollTop)), maxScroll);\n    const thumbStart = maxScroll === 0 ? 0 : Math.round((s / maxScroll) * travel);\n\n    const glyphs = [];\n    for (let i = 0; i < view; i++) {\n        glyphs.push(i >= thumbStart && i < thumbStart + thumbSize ? BAR_THUMB : BAR_TRACK);\n    }\n    return glyphs;\n}\n\n/** ⌥/Ctrl + arrows and PgUp/PgDn → pageUp / pageDown actions. */\nexport const PAGE_SCROLL_KEY_BINDINGS = [\n    { key: \"upArrow\", meta: true, caption: \"page\", action: \"pageUp\", order: 0 },\n    { key: \"downArrow\", meta: true, caption: \"page\", action: \"pageDown\", order: 0 },\n    { key: \"upArrow\", ctrl: true, caption: \"page\", action: \"pageUp\", order: 0 },\n    { key: \"downArrow\", ctrl: true, caption: \"page\", action: \"pageDown\", order: 0 },\n    { key: \"pageUp\", caption: \"page\", action: \"pageUp\", order: 0 },\n    { key: \"pageDown\", caption: \"page\", action: \"pageDown\", order: 0 },\n];\n","/**\n * Key-binding helpers for showScreen (matching + footer labels).\n *\n * Bindings may set `meta` / `ctrl` / `shift` booleans. Plain bindings (flags\n * omitted) do not match when that modifier is held, so `↑` and `⌥↑` can coexist.\n */\n\n/**\n * Stable identity for replace/remove (key + modifiers).\n * @param {{ key: string, meta?: boolean, ctrl?: boolean, shift?: boolean }} b\n */\nexport function bindingIdentity(b) {\n    return [\n        String(b?.key ?? \"\"),\n        b?.meta ? \"m\" : \"\",\n        b?.ctrl ? \"c\" : \"\",\n        b?.shift ? \"s\" : \"\",\n    ].join(\"|\");\n}\n\n/**\n * @param {{ key: string, meta?: boolean, ctrl?: boolean, shift?: boolean }} binding\n * @param {string} input\n * @param {import(\"ink\").Key} key\n */\nexport function bindingMatchesInput(binding, input, key) {\n    if (!binding?.key) return false;\n\n    let keyMatches = false;\n    if (key?.[binding.key]) {\n        keyMatches = true;\n    } else if (input === binding.key) {\n        keyMatches = true;\n    } else if (key?.name === binding.key) {\n        keyMatches = true;\n    }\n    if (!keyMatches) return false;\n\n    // Explicit true → require; explicit false → forbid; omitted → forbid if pressed\n    // (so plain upArrow does not fire for meta+up).\n    const modOk = (flag, pressed) => {\n        if (flag === true) return !!pressed;\n        if (flag === false) return !pressed;\n        return !pressed;\n    };\n\n    // Ink's useInput sets `meta: true` whenever `name === \"escape\"` (Escape is\n    // the terminal meta prefix). Treat that as a lone Esc, not Option+key.\n    const inkEscapeMeta = binding.key === \"escape\" && key?.escape;\n    if (!inkEscapeMeta && !modOk(binding.meta, key?.meta)) return false;\n    if (!modOk(binding.ctrl, key?.ctrl)) return false;\n    if (binding.shift !== undefined && !!key?.shift !== !!binding.shift) return false;\n\n    return true;\n}\n\nconst KEY_LABELS = {\n    escape: \"esc\",\n    leftArrow: \"←\",\n    rightArrow: \"→\",\n    upArrow: \"↑\",\n    downArrow: \"↓\",\n    return: \"enter\",\n    pageUp: \"PgUp\",\n    pageDown: \"PgDn\",\n};\n\n/**\n * Human label for one binding (modifiers + key), e.g. `⌥↑`, `^↓`, `PgUp`.\n * @param {{ key: string, meta?: boolean, ctrl?: boolean, shift?: boolean }} binding\n */\nexport function formatBindingKey(binding) {\n    let label = KEY_LABELS[binding.key] || binding.key;\n    if (binding.shift) label = `⇧${label}`;\n    if (binding.ctrl) label = `^${label}`;\n    // ink `meta` is Option/Alt on macOS (⌘ is usually eaten by the terminal).\n    if (binding.meta) label = `⌥${label}`;\n    return label;\n}\n","/**\n * Ink's log-update always does eraseLines(whole frame) + reprint. That blank\n * intermediate is the flicker. We intercept those writes and update only\n * changed lines in place (like less).\n *\n * Ink writes `yogaOutput + \"\\n\"`. After that, the cursor sits on a new empty\n * line — not on a trailing content row. split(\"\\n\") includes a final \"\" for\n * that newline; CUU must use the content-row count, not the split length.\n */\n\nconst ESC = \"\\u001b[\";\nconst ERASE_LINE = `${ESC}2K`;\nconst CURSOR_UP = `${ESC}1A`;\nconst CURSOR_LEFT = `${ESC}G`;\n\n/** Same formula as ansi-escapes `eraseLines(count)`. */\nexport function inkEraseLines(count) {\n    let clear = \"\";\n    for (let i = 0; i < count; i++) {\n        clear += ERASE_LINE + (i < count - 1 ? CURSOR_UP : \"\");\n    }\n    if (count) clear += CURSOR_LEFT;\n    return clear;\n}\n\nconst ERASE_LINES_RE = /^(?:\\u001b\\[2K\\u001b\\[1A)*\\u001b\\[2K\\u001b\\[G/;\nconst CLEAR_TERMINAL_RE = /^\\u001b\\[2J(?:\\u001b\\[3J)?(?:\\u001b\\[H|\\u001b\\[0f)?/;\n\nexport function splitInkLogWrite(str) {\n    const s = String(str ?? \"\");\n    if (CLEAR_TERMINAL_RE.test(s)) {\n        return { kind: \"clear\", body: s };\n    }\n    const m = s.match(ERASE_LINES_RE);\n    if (m) {\n        return { kind: \"frame\", body: s.slice(m[0].length) };\n    }\n    return { kind: \"raw\", body: s };\n}\n\nexport function splitFrameLines(body) {\n    return String(body ?? \"\").split(\"\\n\");\n}\n\n/** Drop the trailing \"\" that split() adds for Ink's final newline. */\nexport function contentRows(lines) {\n    const rows = Array.isArray(lines) ? lines.slice() : [];\n    if (rows.length > 0 && rows[rows.length - 1] === \"\") rows.pop();\n    return rows;\n}\n\n/**\n * Cursor is on the empty line after the previous frame. Move to the first\n * content row and rewrite only diffs, then park on the line after the new\n * last content row (Ink's convention).\n */\nexport function paintFrameDiff(prevLines, nextLines) {\n    const prev = contentRows(prevLines);\n    const next = contentRows(nextLines);\n    if (prev.length === 0 && next.length === 0) return \"\";\n\n    let out = \"\";\n    if (prev.length > 0) {\n        out += `${ESC}${prev.length}A`;\n    }\n\n    for (let i = 0; i < next.length; i++) {\n        if (prev[i] !== next[i]) {\n            out += ERASE_LINE + CURSOR_LEFT + next[i];\n        }\n        out += \"\\n\";\n    }\n\n    const leftovers = prev.length - next.length;\n    if (leftovers > 0) {\n        for (let i = 0; i < leftovers; i++) {\n            out += ERASE_LINE;\n            if (i < leftovers - 1) out += \"\\n\";\n        }\n        if (leftovers > 1) {\n            out += `${ESC}${leftovers - 1}A`;\n        }\n        out += CURSOR_LEFT;\n    }\n\n    return out;\n}\n\nfunction finishWrite(stdout, payload, enc, done) {\n    const ok = stdout.write(payload, enc);\n    if (typeof done === \"function\") done();\n    return ok;\n}\n\n/**\n * @param {NodeJS.WriteStream} [stdout]\n * @returns {NodeJS.WriteStream}\n */\nexport function createFlickerFreeStdout(stdout = process.stdout) {\n    let prevLines = [];\n\n    const write = (chunk, encoding, cb) => {\n        const done = typeof encoding === \"function\" ? encoding : cb;\n        const enc = typeof encoding === \"function\" ? undefined : encoding;\n        const str = typeof chunk === \"string\" ? chunk : Buffer.from(chunk).toString();\n        const parsed = splitInkLogWrite(str);\n\n        if (parsed.kind === \"clear\") {\n            const after = str.replace(CLEAR_TERMINAL_RE, \"\");\n            prevLines = after ? splitFrameLines(after) : [];\n            return finishWrite(stdout, str, enc, done);\n        }\n\n        if (parsed.kind === \"frame\") {\n            if (parsed.body === \"\") {\n                prevLines = [];\n                return finishWrite(stdout, str, enc, done);\n            }\n            const nextLines = splitFrameLines(parsed.body);\n            if (prevLines.length === 0) {\n                prevLines = nextLines;\n                return finishWrite(stdout, parsed.body, enc, done);\n            }\n            const painted = paintFrameDiff(prevLines, nextLines);\n            prevLines = nextLines;\n            return finishWrite(stdout, painted, enc, done);\n        }\n\n        if (prevLines.length === 0 && parsed.body.includes(\"\\n\")) {\n            prevLines = splitFrameLines(parsed.body);\n        }\n        return stdout.write(chunk, encoding, cb);\n    };\n\n    return new Proxy(stdout, {\n        get(target, prop) {\n            if (prop === \"write\") return write;\n            const value = Reflect.get(target, prop, target);\n            return typeof value === \"function\" ? value.bind(target) : value;\n        },\n    });\n}\n","/**\n * Reusable UI elements for the screen system\n */\n\nimport { createElement as h } from \"react\";\nimport { Box, Text } from \"ink\";\n\n// Types\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * List item component\n */\nexport function ListItem({ \n    children, \n    isSelected = false, \n    color = \"white\", \n    backgroundColor, \n    bold = false, \n    dimColor = false \n}) {\n    return h(Box, {},\n        h(Text, {\n            color: isSelected ? backgroundColor || \"green\" : color,\n            backgroundColor: isSelected ? color : backgroundColor,\n            bold: isSelected || bold,\n            dimColor: !isSelected && dimColor\n        }, children)\n    );\n}\n\n/**\n * Text block component with customizable styling\n */\nexport function TextBlock({ \n    text, \n    color = \"white\", \n    dimmed = false, \n    bold = false, \n    maxWidth: _maxWidth \n}) {\n    return h(Box, {},\n        h(Text, { \n            color, \n            dimColor: dimmed, \n            bold \n        }, text)\n    );\n}\n\n/**\n * Horizontal divider\n */\nexport function Divider({ character = \"─\", width = 80 }) {\n    return h(Box, { marginY: 1 },\n        h(Text, { dimColor: true }, character.repeat(width))\n    );\n}\n\n/**\n * Grid cell component\n */\nexport function GridCell({ \n    children, \n    width, \n    color = \"white\", \n    backgroundColor, \n    bold = false, \n    dimColor = false, \n    align = \"left\" \n}) {\n    return h(Box, { width },\n        h(Text, {\n            color,\n            backgroundColor,\n            bold,\n            dimColor,\n            textAlign: align\n        }, children)\n    );\n}\n\n/**\n * Input field component\n */\nexport function InputField({ prompt, value, onChange: _onChange, onSubmit: _onSubmit }) {\n    return h(Box, { flexDirection: \"column\" },\n        h(Text, {}, prompt),\n        h(Box, { marginTop: 1 },\n            h(Text, { color: \"cyan\" }, \" > \", value, \"_\")\n        )\n    );\n}","/**\n * ScrollableText — wrap long text, line/page scroll, proportional scrollbar.\n *\n *   h(ScrollableText, { ctx, text: json, bindKeys: true })\n *\n * Keys (when bindKeys):\n *   ↑/↓         — one line\n *   ⌥↑/↓ ^↑/↓   — one page (ink `meta` ≈ Option/Alt; ⌘ often never reaches the TTY)\n *   PgUp/PgDn   — one page\n */\n\nimport { useState, useEffect, useMemo, useRef, createElement } from \"react\";\nimport { Box, Text } from \"ink\";\nimport { getScreenWidth } from \"./components.js\";\nimport { getScreenBodyRows } from \"./screen-layout.js\";\nimport {\n    BAR_THUMB,\n    BAR_TRACK,\n    PAGE_SCROLL_KEY_BINDINGS,\n    scrollbarGlyphs,\n} from \"./scrollbar.js\";\nimport { nextScrollAfterContentChange, nextScrollAfterUserMove } from \"./follow-scroll.js\";\nimport { padEndVisible, wrapTextLines } from \"./visible-text.js\";\n\nexport { scrollbarGlyphs } from \"./scrollbar.js\";\nexport { wrapTextLines } from \"./visible-text.js\";\n\nconst h = createElement;\n\nconst SCROLL_KEYS = [\n    { key: \"upArrow\", caption: \"scroll\", action: \"scrollUp\", order: 0 },\n    { key: \"downArrow\", caption: \"scroll\", action: \"scrollDown\", order: 0 },\n    ...PAGE_SCROLL_KEY_BINDINGS,\n];\n/**\n * @param {{\n *   ctx: object,\n *   text?: string,\n *   lines?: string[],\n *   maxHeight?: number,\n *   wrap?: boolean,\n *   showScrollbar?: boolean,\n *   showStatus?: boolean,\n *   bindKeys?: boolean,\n *   header?: unknown,\n *   followBottom?: boolean,\n *   reserveRows?: number,\n * }} props\n */\nexport function ScrollableText({\n    ctx,\n    text = \"\",\n    lines: linesProp,\n    maxHeight,\n    wrap = true,\n    showScrollbar = true,\n    showStatus = true,\n    bindKeys = true,\n    header = null,\n    followBottom = false,\n    reserveRows = 0,\n}) {\n    const [scrollTop, setScrollTop] = useState(0);\n    const [following, setFollowing] = useState(() => !!followBottom);\n\n    const extraRows = (header == null ? 0 : 1) + (showStatus ? 1 : 0) + (Number(reserveRows) || 0);\n    const viewportRows = Math.max(\n        4,\n        maxHeight != null ? Math.floor(maxHeight) : getScreenBodyRows({ extraRows }),\n    );\n\n    // Match ScreenContainer inner width: container is term-4, minus border+paddingX → term-8\n    // (same heuristic as ListComponent / ScreenDivider).\n    const contentCols = Math.max(20, getScreenWidth() - 4);\n    // Always reserve the bar column when enabled so wrap width does not jump when overflow starts.\n    const barCols = showScrollbar ? 1 : 0;\n    const textWidth = Math.max(8, contentCols - barCols);\n\n    const allLines = useMemo(() => {\n        if (Array.isArray(linesProp)) return linesProp.map((l) => String(l ?? \"\"));\n        return wrap ? wrapTextLines(text, textWidth) : String(text ?? \"\").split(\"\\n\");\n    }, [linesProp, text, wrap, textWidth]);\n\n    const needsBar = showScrollbar && allLines.length > viewportRows;\n    const maxScroll = Math.max(0, allLines.length - viewportRows);\n    const clamped = Math.min(Math.max(0, scrollTop), maxScroll);\n    const visible = allLines.slice(clamped, clamped + viewportRows);\n    const bar = needsBar ? scrollbarGlyphs(viewportRows, allLines.length, clamped) : null;\n\n    const maxScrollRef = useRef(maxScroll);\n    const pageSizeRef = useRef(viewportRows);\n    const scrollTopRef = useRef(scrollTop);\n    const followingRef = useRef(following);\n    maxScrollRef.current = maxScroll;\n    pageSizeRef.current = viewportRows;\n    scrollTopRef.current = scrollTop;\n    followingRef.current = following;\n\n    useEffect(() => {\n        const next = nextScrollAfterContentChange({\n            following: followBottom && followingRef.current,\n            scrollTop: scrollTopRef.current,\n            maxScroll,\n        });\n        if (next.scrollTop !== scrollTopRef.current) setScrollTop(next.scrollTop);\n        if (followBottom && next.following !== followingRef.current) setFollowing(next.following);\n    }, [maxScroll, followBottom]);\n\n    const applyUserScroll = (delta) => {\n        const next = nextScrollAfterUserMove(scrollTopRef.current, maxScrollRef.current, delta);\n        setScrollTop(next.scrollTop);\n        if (followBottom) setFollowing(next.following);\n        // Do not ctx.update() — that remounts the bordered Screen and flashes.\n        // Slot keys stay `slot-i` so Ink patches line text in place (like less).\n    };\n\n    useEffect(() => {\n        if (!ctx || !bindKeys) return undefined;\n\n        ctx.setKeyBinding(SCROLL_KEYS);\n\n        ctx.setAction(\"scrollUp\", () => applyUserScroll(-1));\n        ctx.setAction(\"scrollDown\", () => applyUserScroll(1));\n        ctx.setAction(\"pageUp\", () => applyUserScroll(-pageSizeRef.current));\n        ctx.setAction(\"pageDown\", () => applyUserScroll(pageSizeRef.current));\n\n        return undefined;\n    }, [ctx, bindKeys, followBottom]);\n\n    const status =\n        allLines.length === 0\n            ? \"empty\"\n            : `lines ${clamped + 1}-${Math.min(clamped + visible.length, allLines.length)} of ${allLines.length}` +\n              (needsBar ? \" · ⌥↑/↓ or PgUp/Dn page\" : \"\") +\n              (followBottom && following ? \" · follow\" : followBottom ? \" · follow off\" : \"\");\n\n    // Fixed-width rows + stable slot keys: scrolling updates text, does not remount.\n    // Always emit `viewportRows` slots so the pane height (and Screen border) stay put.\n    const rowNodes = [];\n    for (let i = 0; i < viewportRows; i++) {\n        const line = visible[i] ?? \"\";\n        const glyph = bar ? bar[i] ?? BAR_TRACK : showScrollbar ? \" \" : \"\";\n        const isThumb = glyph === BAR_THUMB;\n        rowNodes.push(\n            h(\n                Box,\n                { key: `slot-${i}`, flexDirection: \"row\", width: contentCols, flexShrink: 0 },\n                h(\n                    Box,\n                    { width: textWidth, flexShrink: 0 },\n                    h(Text, { wrap: \"truncate\" }, padEndVisible(line, textWidth)),\n                ),\n                showScrollbar\n                    ? h(Box, { width: 1, flexShrink: 0 }, h(Text, { color: isThumb ? \"cyan\" : \"gray\" }, glyph))\n                    : null,\n            ),\n        );\n    }\n\n    return h(\n        Box,\n        { flexDirection: \"column\", overflow: \"hidden\" },\n        header == null\n            ? null\n            : typeof header === \"string\"\n              ? h(Text, { color: \"gray\" }, header)\n              : header,\n        showStatus ? h(Text, { color: \"gray\" }, status) : null,\n        ...rowNodes,\n    );\n}\n","/**\n * Tail-follow helpers for ScrollableText.\n * Follow while the viewport is pinned to the last line; leave follow on\n * scroll-up; resume when the user scrolls back to the bottom.\n */\n\nexport function clampScroll(scrollTop, maxScroll) {\n    const max = Math.max(0, Number(maxScroll) || 0);\n    const top = Number(scrollTop) || 0;\n    return Math.min(Math.max(0, top), max);\n}\n\nexport function isScrolledToBottom(scrollTop, maxScroll) {\n    return clampScroll(scrollTop, maxScroll) >= Math.max(0, Number(maxScroll) || 0);\n}\n\nexport function nextScrollAfterUserMove(scrollTop, maxScroll, delta) {\n    const next = clampScroll((Number(scrollTop) || 0) + (Number(delta) || 0), maxScroll);\n    return { scrollTop: next, following: isScrolledToBottom(next, maxScroll) };\n}\n\nexport function nextScrollAfterContentChange({ following, scrollTop, maxScroll }) {\n    const max = Math.max(0, Number(maxScroll) || 0);\n    if (following) return { scrollTop: max, following: true };\n    const next = clampScroll(scrollTop, max);\n    return { scrollTop: next, following: isScrolledToBottom(next, max) };\n}\n","/**\n * Typed + pasted text for Ink `useInput`.\n *\n * Ink calls the handler once with the full string when the user pastes more\n * than one character. Terminals also wrap paste in CSI 200~/201~ (bracketed\n * paste); those markers must not land in the field.\n */\n\nconst BRACKETED_PASTE_RE = /\\u001b\\[200~|\\u001b\\[201~|\\[200~|\\[201~/g;\nconst CONTROL_RE = /[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]/g;\n\nexport function sanitizeTextInput(input, { allowNewlines = false } = {}) {\n    let s = String(input ?? \"\").replace(BRACKETED_PASTE_RE, \"\");\n    if (!allowNewlines) s = s.replace(/[\\r\\n]+/g, \"\");\n    else s = s.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n    return s.replace(CONTROL_RE, \"\");\n}\n\nfunction isTextInsertKey(key) {\n    if (!key) return true;\n    if (key.return || key.escape || key.tab) return false;\n    if (key.backspace || key.delete) return false;\n    if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow) return false;\n    if (key.pageUp || key.pageDown) return false;\n    if (key.ctrl) return false;\n    return true;\n}\n\n/**\n * @param {string} current\n * @param {string} input\n * @param {object} key\n * @param {{ allowNewlines?: boolean, accept?: RegExp }} [opts]\n * @returns {string|null} next value, or null if this key is not text\n */\nexport function nextTextInputValue(current, input, key, opts = {}) {\n    const cur = String(current ?? \"\");\n    if (key?.backspace || key?.delete) return cur.slice(0, -1);\n    if (!isTextInsertKey(key)) return null;\n\n    let chunk = sanitizeTextInput(input, opts);\n    if (opts.accept instanceof RegExp) {\n        chunk = [...chunk].filter((ch) => opts.accept.test(ch)).join(\"\");\n    }\n    if (!chunk) return null;\n    return cur + chunk;\n}\n","/**\n * Utility functions for Screen System\n */\n\n/**\n * Build breadcrumb-style title\n * @param parts - Parts of the breadcrumb path\n * @returns Formatted breadcrumb\n *\n * Examples:\n *   buildBreadcrumb(['Menu']) → 'Menu'\n *   buildBreadcrumb(['Menu', 'Info']) → '←  Info'\n *   buildBreadcrumb(['Menu', 'Words', 'nefarious']) → '←  Words  ←  nefarious'\n */\nexport function buildBreadcrumb(parts) {\n    if (parts.length === 0) return \"\";\n    if (parts.length === 1) return parts[0];\n\n    // Skip first part (root), add arrows with spaces to rest\n    return parts.slice(1).map(part => `←  ${part}`).join(\"  \");\n}\n\n/**\n * Create multi-line breadcrumb with details\n * @param path - Navigation path\n * @param suffix - Additional suffix (e.g., 'Details')\n * @returns Formatted breadcrumb with suffix\n *\n * Example:\n *   buildDetailBreadcrumb(['Menu', 'Words', 'nefarious'], 'Details')\n *   → '←  Words  ←  nefarious Details'\n */\nexport function buildDetailBreadcrumb(path, suffix = \"\") {\n    if (path.length <= 1) {\n        return suffix ? `←  ${suffix}` : path[0] || \"\";\n    }\n\n    const breadcrumb = buildBreadcrumb(path);\n    return suffix ? `${breadcrumb} ${suffix}` : breadcrumb;\n}\n","/**\n * Footer builder - composes footer messages from multiple sources\n */\n\n\n\n\n\n\n\n\n\n/**\n * Build footer lines from multiple message sources\n *\n * @param config - Footer configuration object\n * @returns Array of footer lines\n */\nexport function buildFooter(config = {}) {\n    const {\n        navigation = null,\n        actions = null,\n        info = null,\n        escape = \"Esc to go back\",\n        custom = null\n    } = config;\n\n    const lines = [];\n\n    // Build main help line (navigation + actions + escape)\n    const mainParts = [];\n\n    if (navigation) {\n        mainParts.push(navigation);\n    }\n\n    if (actions) {\n        mainParts.push(actions);\n    }\n\n    if (escape) {\n        mainParts.push(escape);\n    }\n\n    if (mainParts.length > 0) {\n        lines.push(mainParts.join(\", \"));\n    }\n\n    // Add info line if present\n    if (info) {\n        const infoLines = Array.isArray(info) ? info : [info];\n        lines.push(...infoLines);\n    }\n\n    // Add custom lines if present\n    if (custom) {\n        const customLines = Array.isArray(custom) ? custom : [custom];\n        lines.push(...customLines);\n    }\n\n    return lines;\n}\n\n/**\n * Predefined footer configurations for common screen types\n */\nexport const FooterPresets = {\n    /**\n     * Menu screen footer\n     */\n    menu: (customInfo = null) => buildFooter({\n        navigation: \"↑/↓ to navigate\",\n        actions: \"Enter to select\",\n        escape: \"Esc to go back\",\n        info: customInfo\n    }),\n\n    /**\n     * Word grid footer\n     */\n    wordGrid: (totalWords) => buildFooter({\n        navigation: \"↑↓←→ to navigate\",\n        actions: \"Enter to select\",\n        escape: \"Esc to go back\",\n        info: `Total: ${totalWords} words`\n    }),\n\n    /**\n     * Text input footer\n     */\n    textInput: () => buildFooter({\n        actions: \"Type and press Enter to submit\",\n        escape: \"Esc to cancel\"\n    }),\n\n    /**\n     * Info/static screen footer\n     */\n    info: () => buildFooter({\n        escape: \"Esc to continue\"\n    }),\n\n    /**\n     * Main menu footer (escape exits)\n     */\n    mainMenu: () => buildFooter({\n        navigation: \"↑/↓ to navigate\",\n        actions: \"Enter to select\",\n        escape: \"Esc to exit\"\n    }),\n\n    /**\n     * Action menu footer (for word cards, etc.)\n     */\n    actionMenu: (hasAudio = false) => {\n        const parts = buildFooter({\n            navigation: \"↑/↓ to navigate\",\n            actions: \"Enter to select\",\n            escape: \"Esc to go back\"\n        });\n\n        if (hasAudio) {\n            parts.push(\"Audio available\");\n        }\n\n        return parts;\n    }\n};\n\n/**\n * Combine multiple footer messages into organized lines\n * Smart grouping of related messages\n *\n * @param messages - Individual footer messages\n * @returns Organized footer lines\n */\nexport function organizeFooterMessages(messages) {\n    if (!messages || messages.length === 0) {\n        return [\"Esc to go back\"];\n    }\n\n    // Group similar messages\n    const navigation = messages.filter(m => m.includes(\"↑\") || m.includes(\"↓\") || m.includes(\"←\") || m.includes(\"→\"));\n    const actions = messages.filter(m => m.includes(\"Enter\") || m.includes(\"select\") || m.includes(\"submit\"));\n    const escape = messages.filter(m => m.includes(\"Esc\"));\n    const others = messages.filter(m =>\n        !navigation.includes(m) &&\n        !actions.includes(m) &&\n        !escape.includes(m)\n    );\n\n    const lines = [];\n\n    // Combine navigation, actions, and escape on one line\n    const mainLine = [...navigation, ...actions, ...escape].join(\", \");\n    if (mainLine) lines.push(mainLine);\n\n    // Add other messages as separate lines\n    lines.push(...others);\n\n    return lines;\n}\n"],"mappings":"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","names":["React","import_react","import_ink","import_react","import_ink","h","React","import_react","import_ink","h","React","chalk","h","import_react","import_ink","h","import_react","import_ink","h"]}