@nmakarov/cli-toolkit 0.81.0 → 0.82.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-runner.cjs +73 -18
- package/dist/cli-runner.cjs.map +1 -1
- package/dist/cli-runner.js +75 -20
- package/dist/cli-runner.js.map +1 -1
- package/dist/index.cjs +77 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +75 -20
- package/dist/index.js.map +1 -1
- package/dist/init.cjs +73 -18
- package/dist/init.cjs.map +1 -1
- package/dist/init.js +75 -20
- package/dist/init.js.map +1 -1
- package/dist/screen.cjs +70 -19
- package/dist/screen.cjs.map +1 -1
- package/dist/screen.js +66 -19
- package/dist/screen.js.map +1 -1
- package/package.json +1 -1
package/dist/screen.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/screen/index.js","../src/screen/screens.js","../src/screen/components.js","../src/screen/list-components.js","../src/screen/scrollbar.js","../src/screen/key-bindings.js","../src/screen/ui-elements.js","../src/screen/scrollable-text.js","../src/screen/follow-scroll.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} from \"./screens.js\";\n\n// Reusable components\nexport { MultiColumnListComponent, MultiColumnListWithPreviewComponent, ListComponent } from \"./list-components.js\";\nexport { ScreenContainer, ScreenRow, ScreenTitle, ScreenBody, ScreenFooter, ScreenDivider } from \"./components.js\";\nexport { ListItem, TextBlock, Divider, GridCell, InputField } from \"./ui-elements.js\";\nexport { ScrollableText, wrapTextLines, scrollbarGlyphs } from \"./scrollable-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\";\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, Text } from \"ink\";\nimport { ScreenContainer, ScreenRow, ScreenTitle, ScreenDivider, ScreenFooter } from \"./components.js\";\nimport { MultiColumnListComponent, MultiColumnListWithPreviewComponent, ListComponent } from \"./list-components.js\";\nimport {\n bindingIdentity,\n bindingMatchesInput,\n formatBindingKey,\n} from \"./key-bindings.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 });\n\n return Object.values(groups);\n}\n\n/**\n * Format key bindings for footer (returns array of strings/components)\n */\nexport function formatKeyBindings(bindings, mode = \"long\") {\n // Resolve function captions\n const resolvedBindings = bindings.map(binding => {\n let resolvedCaption = binding.caption;\n\n // If caption is a function, call it\n if (typeof binding.caption === \"function\") {\n resolvedCaption = binding.caption();\n }\n\n return {\n ...binding,\n resolvedCaption\n };\n });\n\n const groups = groupKeyBindings(resolvedBindings.map(b => ({\n ...b,\n caption: typeof b.resolvedCaption === \"string\" ? b.resolvedCaption : \"\"\n })));\n\n // Sort by order\n groups.sort((a, b) => a.order - b.order);\n\n const items = [];\n\n groups.forEach(group => {\n // Check if any binding in this group has a component/custom caption\n const bindingWithCustom = resolvedBindings.find(b =>\n group.keys.includes(b.key) && typeof b.resolvedCaption !== \"string\"\n );\n\n if (bindingWithCustom && bindingWithCustom.resolvedCaption) {\n // Use the full custom display (component or complex structure)\n items.push(bindingWithCustom.resolvedCaption );\n } else {\n // Standard format with string caption\n const keyStr = formatKeys(group.keys);\n\n if (mode === \"long\") {\n items.push(`${keyStr} to ${group.caption}`);\n } else {\n items.push(keyStr);\n }\n }\n });\n\n return items;\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 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 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 // 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 // Build footer\n const footerLines = [];\n\n // Add key bindings (returns array of strings/components)\n const bindingItems = formatKeyBindings(keyBindings, \"long\");\n\n if (bindingItems.length > 0) {\n // Build a single line with all binding items separated by \", \"\n const bindingsLine = [];\n bindingItems.forEach((item, idx) => {\n if (idx > 0) {\n bindingsLine.push(\", \");\n }\n bindingsLine.push(item);\n });\n\n // If all items are strings, join them; otherwise create a Box\n const allStrings = bindingItems.every(item => typeof item === \"string\");\n if (allStrings) {\n footerLines.push(bindingsLine.join(\"\"));\n } else {\n // Mixed strings and components - wrap all strings in Text components\n const wrappedBindingsLine = bindingsLine.map(item => \n typeof item === \"string\" ? h(Text, {}, item) : item\n );\n footerLines.push(wrappedBindingsLine);\n }\n }\n\n // Add custom footer items\n customFooterItems.forEach(item => {\n if (typeof item === \"string\") {\n footerLines.push(item);\n } else {\n footerLines.push(item);\n }\n });\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, { lines: footerLines })\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 });\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 { createElement as h } from \"react\";\nimport { Box, Text } from \"ink\";\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\n return h(Box, {\n flexDirection: \"column\",\n marginTop: 1,\n borderStyle: \"single\",\n borderColor: \"cyan\",\n paddingX: 1,\n width: width // Use the calculated width directly\n }, children);\n}\n\n/**\n * Screen row - just a wrapper for spacing, borders handled by container\n */\nexport function ScreenRow({ children }) {\n return h(Box, { flexDirection: \"column\" }, children);\n}\n\n/**\n * Screen Title - first line inside container (left-aligned, breadcrumb-style)\n */\nexport function ScreenTitle({ text }) {\n return h(ScreenRow, {},\n h(Text, { bold: true, color: \"cyan\" }, 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/**\n * Screen Footer - bottom area with key bindings and status\n * \n * @example\n * <ScreenFooter lines={[\"esc to go back\", \"enter to select\"]} />\n * \n * @example\n * <ScreenFooter \n * lines={[\"esc to go back\", \"enter to select\"]} \n * textStyle={{ color: \"white\" }}\n * />\n * \n * @example\n * <ScreenFooter \n * lines={[\"esc to go back\", \"enter to select\"]} \n * textStyle={{ dimColor: false, color: \"green\" }}\n * />\n */\nexport function ScreenFooter({ lines, textStyle }) {\n const defaultTextStyle = {\n dimColor: true,\n color: \"white\"\n };\n \n const finalTextStyle = { ...defaultTextStyle, ...textStyle };\n\n // Flatten nested arrays and ensure all items are properly wrapped\n const flattenAndWrap = (items, keyPrefix = \"\") => {\n const result = [];\n let keyIndex = 0;\n\n items.forEach((item, index) => {\n if (Array.isArray(item)) {\n // Handle nested arrays\n const nested = flattenAndWrap(item, `${keyPrefix}-${index}`);\n result.push(...nested);\n } else if (typeof item === \"string\") {\n // Wrap strings in Text components\n result.push(\n h(Text, { key: `${keyPrefix}-${keyIndex++}`, ...finalTextStyle }, item)\n );\n } else {\n // JSX elements - add key if missing\n const element = item ;\n if (element.key === null || element.key === undefined) {\n result.push(\n h(Text, { key: `${keyPrefix}-${keyIndex++}`, ...finalTextStyle }, element)\n );\n } else {\n result.push(element);\n }\n }\n });\n\n return result;\n };\n\n const wrappedItems = flattenAndWrap(lines);\n\n return h(Box, { flexDirection: \"column\" },\n h(Box, { flexDirection: \"row\" }, ...wrappedItems)\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 // Create caption that includes sort status\n const sortCaption = () => {\n if (sortOrder === \"none\") {\n return h(Text, {}, \"s to toggle sort\");\n } else {\n const sortLabel = sortOrder === \"asc\" ? \"ASC\" : \"DESC\";\n return h(Text, {}, \n \"s to toggle \",\n h(Text, { color: \"white\", bold: true }, \"sort\"),\n \" \",\n h(Text, highlightStyle, ` ${sortLabel} `)\n );\n }\n };\n\n ctx.setKeyBinding([\n ...navBindings,\n {\n key: \"s\",\n caption: sortCaption,\n action: \"toggleSort\",\n order: 5,\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-${actualIndex}`, color: \"white\" }, arrowPrefix),\n h(Text, { key: `marker-${actualIndex}`, color: \"white\" }, selectionPrefix),\n h(\n Text,\n {\n key: `name-${actualIndex}`,\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-${actualIndex}`, color: \"white\" }, arrowPrefix),\n h(Text, { key: `marker-${actualIndex}`, color: \"white\" }, selectionPrefix),\n renderItem(clipped, isSelected, displayIndex),\n );\n\n return h(ScreenRow, {\n key: `item-${actualIndex}`,\n children: appendBar(row, displayIndex),\n });\n }\n\n return h(ScreenRow, {\n key: `item-${actualIndex}`,\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 // shift is often used with letters; for arrows we still treat omitted as \"any\"\n // only for shift — meta/ctrl are the page-jump modifiers we care about.\n if (!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 * 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 {\n BAR_THUMB,\n BAR_TRACK,\n PAGE_SCROLL_KEY_BINDINGS,\n scrollbarGlyphs,\n} from \"./scrollbar.js\";\nimport { nextScrollAfterContentChange, nextScrollAfterUserMove } from \"./follow-scroll.js\";\n\nexport { scrollbarGlyphs } from \"./scrollbar.js\";\n\nconst h = createElement;\n\n/**\n * Hard-wrap text to `cols` (keeps empty lines).\n * @param {string} text\n * @param {number} cols\n * @returns {string[]}\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 let rest = raw;\n while (rest.length > w) {\n out.push(rest.slice(0, w));\n rest = rest.slice(w);\n }\n if (rest.length > 0) out.push(rest);\n }\n return out;\n}\n\nfunction padEndVisible(s, w) {\n const t = String(s ?? \"\");\n if (t.length >= w) return t.slice(0, w);\n return t + \" \".repeat(w - t.length);\n}\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 * }} 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}) {\n const [scrollTop, setScrollTop] = useState(0);\n const [following, setFollowing] = useState(() => !!followBottom);\n const [, bump] = useState(0);\n\n const termRows = process.stdout.rows || 24;\n const viewportRows = Math.max(\n 4,\n maxHeight != null ? Math.floor(maxHeight) : Math.max(8, termRows - 8),\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 bump((n) => n + 1);\n ctx?.update?.();\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 // Single Text per row (not a row Box): avoids yoga width surprises; ASCII bar is 1 cell.\n const rowNodes = visible.map((line, i) => {\n const body = padEndVisible(line, textWidth);\n const glyph = bar ? bar[i] ?? BAR_TRACK : showScrollbar ? \" \" : \"\";\n const isThumb = glyph === BAR_THUMB;\n return h(\n Text,\n { key: `L${clamped + i}` },\n body,\n glyph\n ? h(Text, { color: isThumb ? \"cyan\" : \"gray\" }, glyph)\n : null,\n );\n });\n\n // Pad short final page so the scrollbar track stays full height.\n if (bar && visible.length < viewportRows) {\n for (let i = visible.length; i < viewportRows; i++) {\n const glyph = bar[i] ?? BAR_TRACK;\n rowNodes.push(\n h(\n Text,\n { key: `pad${i}` },\n padEndVisible(\"\", textWidth),\n h(Text, { color: glyph === BAR_THUMB ? \"cyan\" : \"gray\" }, glyph),\n ),\n );\n }\n }\n\n return h(\n Box,\n { flexDirection: \"column\" },\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 * 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","useState","useEffect","useRef","useMemo","createElement","Box","Text","useInput","useState","h","Text","Box","Text","h","Box","Text","useState","h","Text","h","Box","Text","useState","useEffect","useRef","createElement","Box","Text","h","createElement","useState","useRef","useEffect","Text","Box"]}
|
|
1
|
+
{"version":3,"sources":["../src/screen/index.js","../src/screen/screens.js","../src/screen/components.js","../src/screen/list-components.js","../src/screen/scrollbar.js","../src/screen/key-bindings.js","../src/screen/ui-elements.js","../src/screen/scrollable-text.js","../src/screen/follow-scroll.js","../src/screen/visible-text.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} from \"./screens.js\";\n\n// Reusable components\nexport { MultiColumnListComponent, MultiColumnListWithPreviewComponent, ListComponent } from \"./list-components.js\";\nexport { ScreenContainer, ScreenRow, ScreenTitle, ScreenBody, ScreenFooter, ScreenDivider } from \"./components.js\";\nexport { ListItem, TextBlock, Divider, GridCell, InputField } from \"./ui-elements.js\";\nexport { ScrollableText, wrapTextLines, scrollbarGlyphs } from \"./scrollable-text.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\";\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, Text } from \"ink\";\nimport { ScreenContainer, ScreenRow, ScreenTitle, ScreenDivider, ScreenFooter } from \"./components.js\";\nimport { MultiColumnListComponent, MultiColumnListWithPreviewComponent, ListComponent } from \"./list-components.js\";\nimport {\n bindingIdentity,\n bindingMatchesInput,\n formatBindingKey,\n} from \"./key-bindings.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 });\n\n return Object.values(groups);\n}\n\n/**\n * Format key bindings for footer (returns array of strings/components)\n */\nexport function formatKeyBindings(bindings, mode = \"long\") {\n // Resolve function captions\n const resolvedBindings = bindings.map(binding => {\n let resolvedCaption = binding.caption;\n\n // If caption is a function, call it\n if (typeof binding.caption === \"function\") {\n resolvedCaption = binding.caption();\n }\n\n return {\n ...binding,\n resolvedCaption\n };\n });\n\n const groups = groupKeyBindings(resolvedBindings.map(b => ({\n ...b,\n caption: typeof b.resolvedCaption === \"string\" ? b.resolvedCaption : \"\"\n })));\n\n // Sort by order\n groups.sort((a, b) => a.order - b.order);\n\n const items = [];\n\n groups.forEach(group => {\n // Check if any binding in this group has a component/custom caption\n const bindingWithCustom = resolvedBindings.find(b =>\n group.keys.includes(b.key) && typeof b.resolvedCaption !== \"string\"\n );\n\n if (bindingWithCustom && bindingWithCustom.resolvedCaption) {\n // Use the full custom display (component or complex structure)\n items.push(bindingWithCustom.resolvedCaption );\n } else {\n // Standard format with string caption\n const keyStr = formatKeys(group.keys);\n\n if (mode === \"long\") {\n items.push(`${keyStr} to ${group.caption}`);\n } else {\n items.push(keyStr);\n }\n }\n });\n\n return items;\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 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 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 // 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 // Build footer\n const footerLines = [];\n\n // Add key bindings (returns array of strings/components)\n const bindingItems = formatKeyBindings(keyBindings, \"long\");\n\n if (bindingItems.length > 0) {\n // Build a single line with all binding items separated by \", \"\n const bindingsLine = [];\n bindingItems.forEach((item, idx) => {\n if (idx > 0) {\n bindingsLine.push(\", \");\n }\n bindingsLine.push(item);\n });\n\n // If all items are strings, join them; otherwise create a Box\n const allStrings = bindingItems.every(item => typeof item === \"string\");\n if (allStrings) {\n footerLines.push(bindingsLine.join(\"\"));\n } else {\n // Mixed strings and components - wrap all strings in Text components\n const wrappedBindingsLine = bindingsLine.map(item => \n typeof item === \"string\" ? h(Text, {}, item) : item\n );\n footerLines.push(wrappedBindingsLine);\n }\n }\n\n // Add custom footer items\n customFooterItems.forEach(item => {\n if (typeof item === \"string\") {\n footerLines.push(item);\n } else {\n footerLines.push(item);\n }\n });\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, { lines: footerLines })\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 });\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 { createElement as h } from \"react\";\nimport { Box, Text } from \"ink\";\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\n return h(Box, {\n flexDirection: \"column\",\n marginTop: 1,\n borderStyle: \"single\",\n borderColor: \"cyan\",\n paddingX: 1,\n width: width // Use the calculated width directly\n }, children);\n}\n\n/**\n * Screen row - just a wrapper for spacing, borders handled by container\n */\nexport function ScreenRow({ children }) {\n return h(Box, { flexDirection: \"column\" }, children);\n}\n\n/**\n * Screen Title - first line inside container (left-aligned, breadcrumb-style)\n */\nexport function ScreenTitle({ text }) {\n return h(ScreenRow, {},\n h(Text, { bold: true, color: \"cyan\" }, 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/**\n * Screen Footer - bottom area with key bindings and status\n * \n * @example\n * <ScreenFooter lines={[\"esc to go back\", \"enter to select\"]} />\n * \n * @example\n * <ScreenFooter \n * lines={[\"esc to go back\", \"enter to select\"]} \n * textStyle={{ color: \"white\" }}\n * />\n * \n * @example\n * <ScreenFooter \n * lines={[\"esc to go back\", \"enter to select\"]} \n * textStyle={{ dimColor: false, color: \"green\" }}\n * />\n */\nexport function ScreenFooter({ lines, textStyle }) {\n const defaultTextStyle = {\n dimColor: true,\n color: \"white\"\n };\n \n const finalTextStyle = { ...defaultTextStyle, ...textStyle };\n\n // Flatten nested arrays and ensure all items are properly wrapped\n const flattenAndWrap = (items, keyPrefix = \"\") => {\n const result = [];\n let keyIndex = 0;\n\n items.forEach((item, index) => {\n if (Array.isArray(item)) {\n // Handle nested arrays\n const nested = flattenAndWrap(item, `${keyPrefix}-${index}`);\n result.push(...nested);\n } else if (typeof item === \"string\") {\n // Wrap strings in Text components\n result.push(\n h(Text, { key: `${keyPrefix}-${keyIndex++}`, ...finalTextStyle }, item)\n );\n } else {\n // JSX elements - add key if missing\n const element = item ;\n if (element.key === null || element.key === undefined) {\n result.push(\n h(Text, { key: `${keyPrefix}-${keyIndex++}`, ...finalTextStyle }, element)\n );\n } else {\n result.push(element);\n }\n }\n });\n\n return result;\n };\n\n const wrappedItems = flattenAndWrap(lines);\n\n return h(Box, { flexDirection: \"column\" },\n h(Box, { flexDirection: \"row\" }, ...wrappedItems)\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 // Create caption that includes sort status\n const sortCaption = () => {\n if (sortOrder === \"none\") {\n return h(Text, {}, \"s to toggle sort\");\n } else {\n const sortLabel = sortOrder === \"asc\" ? \"ASC\" : \"DESC\";\n return h(Text, {}, \n \"s to toggle \",\n h(Text, { color: \"white\", bold: true }, \"sort\"),\n \" \",\n h(Text, highlightStyle, ` ${sortLabel} `)\n );\n }\n };\n\n ctx.setKeyBinding([\n ...navBindings,\n {\n key: \"s\",\n caption: sortCaption,\n action: \"toggleSort\",\n order: 5,\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-${actualIndex}`, color: \"white\" }, arrowPrefix),\n h(Text, { key: `marker-${actualIndex}`, color: \"white\" }, selectionPrefix),\n h(\n Text,\n {\n key: `name-${actualIndex}`,\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-${actualIndex}`, color: \"white\" }, arrowPrefix),\n h(Text, { key: `marker-${actualIndex}`, color: \"white\" }, selectionPrefix),\n renderItem(clipped, isSelected, displayIndex),\n );\n\n return h(ScreenRow, {\n key: `item-${actualIndex}`,\n children: appendBar(row, displayIndex),\n });\n }\n\n return h(ScreenRow, {\n key: `item-${actualIndex}`,\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 // shift is often used with letters; for arrows we still treat omitted as \"any\"\n // only for shift — meta/ctrl are the page-jump modifiers we care about.\n if (!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 * 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 {\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 * }} 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}) {\n const [scrollTop, setScrollTop] = useState(0);\n const [following, setFollowing] = useState(() => !!followBottom);\n const [, bump] = useState(0);\n\n const termRows = process.stdout.rows || 24;\n const viewportRows = Math.max(\n 4,\n maxHeight != null ? Math.floor(maxHeight) : Math.max(8, termRows - 8),\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 bump((n) => n + 1);\n ctx?.update?.();\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 row: text pane + 1-col bar so the track is always a straight\n // right edge (ANSI / wrap must not move the glyph).\n const rowNodes = visible.map((line, i) => {\n const glyph = bar ? bar[i] ?? BAR_TRACK : showScrollbar ? \" \" : \"\";\n const isThumb = glyph === BAR_THUMB;\n return h(\n Box,\n { key: `L${clamped + 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 if (bar && visible.length < viewportRows) {\n for (let i = visible.length; i < viewportRows; i++) {\n const glyph = bar[i] ?? BAR_TRACK;\n rowNodes.push(\n h(\n Box,\n { key: `pad${i}`, flexDirection: \"row\", width: contentCols, flexShrink: 0 },\n h(Box, { width: textWidth, flexShrink: 0 }, h(Text, {}, padEndVisible(\"\", textWidth))),\n h(Box, { width: 1, flexShrink: 0 }, h(Text, { color: glyph === BAR_THUMB ? \"cyan\" : \"gray\" }, glyph)),\n ),\n );\n }\n }\n\n return h(\n Box,\n { flexDirection: \"column\" },\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 * 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 * 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","useState","useEffect","useRef","useMemo","createElement","Box","Text","useInput","useState","h","Text","Box","Text","h","Box","Text","useState","h","Text","h","Box","Text","useState","useEffect","useRef","createElement","Box","Text","h","createElement","useState","useRef","useEffect","Box","Text"]}
|