@alcyone-labs/arg-parser 2.14.2 → 3.0.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/README.md +20 -127
- package/dist/config/plugins/index.d.ts +36 -4
- package/dist/config/plugins/index.d.ts.map +1 -1
- package/dist/core/ArgParser.d.ts +124 -464
- package/dist/core/ArgParser.d.ts.map +1 -1
- package/dist/core/FlagManager.d.ts +36 -136
- package/dist/core/FlagManager.d.ts.map +1 -1
- package/dist/core/PromptManager.d.ts +42 -91
- package/dist/core/PromptManager.d.ts.map +1 -1
- package/dist/core/log-path-utils.d.ts +28 -36
- package/dist/core/log-path-utils.d.ts.map +1 -1
- package/dist/core/types.d.ts +83 -592
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.cjs +599 -9658
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +26 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.min.mjs +615 -8224
- package/dist/index.min.mjs.map +1 -1
- package/dist/index.mjs +581 -8881
- package/dist/index.mjs.map +1 -1
- package/dist/plugin/types.d.ts +121 -0
- package/dist/plugin/types.d.ts.map +1 -0
- package/dist/utils/debug-utils.d.ts +4 -26
- package/dist/utils/debug-utils.d.ts.map +1 -1
- package/package.json +12 -73
- package/dist/assets/.dxtignore.template +0 -37
- package/dist/assets/logo_1_small.jpg +0 -0
- package/dist/config/ConfigurationManager.d.ts +0 -82
- package/dist/config/ConfigurationManager.d.ts.map +0 -1
- package/dist/config/plugins/ConfigPlugin.d.ts +0 -60
- package/dist/config/plugins/ConfigPlugin.d.ts.map +0 -1
- package/dist/config/plugins/ConfigPluginRegistry.d.ts +0 -72
- package/dist/config/plugins/ConfigPluginRegistry.d.ts.map +0 -1
- package/dist/config/plugins/TomlConfigPlugin.d.ts +0 -30
- package/dist/config/plugins/TomlConfigPlugin.d.ts.map +0 -1
- package/dist/config/plugins/YamlConfigPlugin.d.ts +0 -29
- package/dist/config/plugins/YamlConfigPlugin.d.ts.map +0 -1
- package/dist/core/ArgParserBase.d.ts +0 -319
- package/dist/core/ArgParserBase.d.ts.map +0 -1
- package/dist/core/dxt-path-resolver.d.ts +0 -100
- package/dist/core/dxt-path-resolver.d.ts.map +0 -1
- package/dist/dxt/DxtGenerator-testUtils.d.ts +0 -22
- package/dist/dxt/DxtGenerator-testUtils.d.ts.map +0 -1
- package/dist/dxt/DxtGenerator.d.ts +0 -120
- package/dist/dxt/DxtGenerator.d.ts.map +0 -1
- package/dist/mcp/ArgParserMcp.d.ts +0 -21
- package/dist/mcp/ArgParserMcp.d.ts.map +0 -1
- package/dist/mcp/mcp-integration.d.ts +0 -86
- package/dist/mcp/mcp-integration.d.ts.map +0 -1
- package/dist/mcp/mcp-lifecycle.d.ts +0 -163
- package/dist/mcp/mcp-lifecycle.d.ts.map +0 -1
- package/dist/mcp/mcp-notifications.d.ts +0 -132
- package/dist/mcp/mcp-notifications.d.ts.map +0 -1
- package/dist/mcp/mcp-prompts.d.ts +0 -132
- package/dist/mcp/mcp-prompts.d.ts.map +0 -1
- package/dist/mcp/mcp-protocol-versions.d.ts +0 -150
- package/dist/mcp/mcp-protocol-versions.d.ts.map +0 -1
- package/dist/mcp/mcp-resources.d.ts +0 -133
- package/dist/mcp/mcp-resources.d.ts.map +0 -1
- package/dist/mcp/mcp-utils.d.ts +0 -20
- package/dist/mcp/mcp-utils.d.ts.map +0 -1
- package/dist/mcp/zod-compatibility.d.ts +0 -74
- package/dist/mcp/zod-compatibility.d.ts.map +0 -1
- package/dist/testing/fuzzy-test-cli.d.ts +0 -5
- package/dist/testing/fuzzy-test-cli.d.ts.map +0 -1
- package/dist/testing/fuzzy-tester.d.ts +0 -101
- package/dist/testing/fuzzy-tester.d.ts.map +0 -1
- package/dist/tui/index.d.ts +0 -281
- package/dist/tui/types.d.ts +0 -60
- package/dist/tui/types.d.ts.map +0 -1
- package/dist/tui.cjs +0 -1060
- package/dist/tui.cjs.map +0 -1
- package/dist/tui.mjs +0 -967
- package/dist/tui.mjs.map +0 -1
package/dist/tui.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tui.mjs","names":["onCleanup","CliRenderer","JSX","useRenderer","ExitGuardProps","children","Element","ExitGuardState","originalExit","process","exit","renderers","Set","activeCount","isExiting","EXIT_GUARD_STATE_KEY","Symbol","for","getExitGuardState","setExitGuardState","state","ExitGuard","props","renderer","bind","guardedExit","code","currentState","exitCode","r","destroy","add","delete","Math","max","undefined","chordTimeout: ReturnType<typeof setTimeout> | null","value: ShortcutContextValue","TuiThemes: Record<string, TuiTheme>","value: ThemeContextValue","hideTimeout: ReturnType<typeof setTimeout> | null","value: ToastContextValue","createContext","createSignal","onCleanup","onMount","useContext","Accessor","JSX","MouseEvent","createComponent","useRenderer","ExitGuard","ShortcutProvider","ShortcutBinding","ThemeProvider","TuiTheme","ToastProvider","cleanupTerminal","enableMouseReporting","switchToAlternateScreen","TuiContextValue","viewportHeight","viewportWidth","exit","code","TuiProviderProps","theme","shortcuts","onScroll","delta","scrollSpeed","reservedRows","children","Element","TuiContext","useTui","context","Error","TuiProvider","props","renderer","setViewportHeight","Math","max","height","setViewportWidth","width","process","exitCode","destroy","handleResize","handleMouseScroll","event","scroll","sign","direction","on","off","contextValue","themeName","name","Provider","value","initial","bindings","_$ssr","_tmpl$","_$escape","For","JSX","useTheme","BreadcrumbProps","segments","separator","accentColor","mutedColor","Breadcrumb","props","Element","current","theme","colors","accent","muted","_$ssr","_tmpl$","_$escape","_$createComponent","each","children","segment","idx","_tmpl$3","_$ssrAttribute","_tmpl$2","createMemo","createSignal","For","Show","Accessor","JSX","useTheme","VirtualListProps","items","T","selectedIndex","onSelect","index","viewportHeight","title","renderItem","item","selected","Element","getLabel","showIndicator","VirtualListResult","scrollOffset","adjustScroll","idx","scrollBy","delta","selectPrevious","selectNext","unwrap","value","VirtualList","props","current","theme","setScrollOffset","newIdx","vh","currentOffset","maxOffset","Math","max","length","o","min","visibleItems","allItems","start","end","slice","map","localIdx","globalIndex","defaultRenderItem","label","String","t","_$ssr","_tmpl$","_$ssrAttribute","_$escape","colors","selection","undefined","background","text","_tmpl$3","_$createComponent","when","children","_tmpl$2","each","createVirtualListController","setSelectedIndex","Show","JSX","useTheme","Breadcrumb","MasterDetailProps","header","breadcrumb","footer","master","Element","detail","masterWidth","headerIcon","MasterDetail","props","current","theme","_$ssr","_tmpl$2","_$ssrAttribute","_$escape","colors","background","accent","_$createComponent","when","length","children","segments","border","_tmpl$","muted","api: NavigatorApi","JSX","TuiTheme","LAYOUT_THEMES","dark","bg","fg","accent","muted","error","success","border","selection","selectionFg","light","monokai","const","LayoutThemeName","LayoutTheme","MasterDetailLayoutProps","header","breadcrumb","footer","theme","masterWidth","children","Element","PanelProps","resolveTheme","MasterDetailLayout","props","t","_$ssr","_tmpl$","_$ssrAttribute","_$escape","length","_tmpl$2","map","segment","idx","_tmpl$4","_tmpl$3","_tmpl$5","MasterPanel","width","_tmpl$6","DetailPanel","_tmpl$7","ListItem","label","selected","_tmpl$8","undefined"],"sources":["../src/tui/runtime/ExitGuard.tsx","../src/tui/shortcuts.ts","../src/tui/themes.ts","../src/tui/toast.ts","../src/tui/tty.ts","../src/tui/app.ts","../src/tui/providers/TuiProvider.tsx","../src/tui/components/Breadcrumb.tsx","../src/tui/components/VirtualList.tsx","../src/tui/components/MasterDetailV2.tsx","../src/tui/components/MasterDetailLayout.ts","../src/tui/components/DrillDownNavigator.ts","../src/tui/components/Card.ts","../src/tui/components/MarkdownBlock.ts","../src/tui/components/Button.ts","../src/tui/layouts/master-detail.tsx","../src/tui/hooks/use-virtual-scroll.ts","../src/tui/hooks/use-mouse.ts"],"sourcesContent":["import { onCleanup } from \"solid-js\";\nimport type { CliRenderer } from \"@opentui/core\";\nimport type { JSX } from \"@opentui/solid\";\nimport { useRenderer } from \"@opentui/solid\";\n\nexport interface ExitGuardProps {\n children: JSX.Element;\n}\n\ntype ExitGuardState = {\n originalExit: typeof process.exit;\n renderers: Set<CliRenderer>;\n activeCount: number;\n isExiting: boolean;\n};\n\nconst EXIT_GUARD_STATE_KEY = Symbol.for(\"@alcyone-labs/arg-parser/tui/ExitGuardState\");\n\nfunction getExitGuardState(): ExitGuardState | undefined {\n return (process as any)[EXIT_GUARD_STATE_KEY] as ExitGuardState | undefined;\n}\n\nfunction setExitGuardState(state: ExitGuardState | undefined): void {\n if (state) {\n (process as any)[EXIT_GUARD_STATE_KEY] = state;\n } else {\n delete (process as any)[EXIT_GUARD_STATE_KEY];\n }\n}\n\nexport function ExitGuard(props: ExitGuardProps): JSX.Element {\n const renderer = useRenderer();\n\n let state = getExitGuardState();\n\n if (!state) {\n const originalExit = process.exit.bind(process) as typeof process.exit;\n\n state = {\n originalExit,\n renderers: new Set<CliRenderer>(),\n activeCount: 0,\n isExiting: false,\n };\n\n setExitGuardState(state);\n\n const guardedExit = ((code?: number): never => {\n const currentState = getExitGuardState();\n if (!currentState) {\n return originalExit(code);\n }\n\n if (currentState.isExiting) {\n return currentState.originalExit(code);\n }\n\n currentState.isExiting = true;\n try {\n if (typeof code === \"number\") {\n process.exitCode = code;\n }\n\n for (const r of currentState.renderers) {\n try {\n r.destroy();\n } catch {\n // Ignore destroy errors during shutdown\n }\n }\n } finally {\n return currentState.originalExit(code);\n }\n }) as typeof process.exit;\n\n process.exit = guardedExit;\n }\n\n state.activeCount++;\n state.renderers.add(renderer);\n\n onCleanup(() => {\n const state = getExitGuardState();\n if (!state) {\n return;\n }\n\n state.renderers.delete(renderer);\n state.activeCount = Math.max(0, state.activeCount - 1);\n\n if (state.activeCount === 0) {\n process.exit = state.originalExit;\n setExitGuardState(undefined);\n }\n });\n\n return props.children;\n}\n","/**\n * TUI Shortcut System\n *\n * Provides keyboard shortcut handling with support for:\n * - Simple shortcuts: \"ctrl+t\", \"escape\"\n * - Chord sequences: \"ctrl+x t\" (press Ctrl+X, then t)\n */\n\nimport { createContext, createSignal, useContext, type Accessor } from \"solid-js\";\nimport type { JSX } from \"@opentui/solid\";\nimport { createComponent } from \"@opentui/solid\";\nimport type { ShortcutBinding } from \"./types\";\n\nexport type { ShortcutBinding };\n\n/**\n * Shortcut context value interface\n */\nexport interface ShortcutContextValue {\n /** Register a shortcut binding, returns cleanup function */\n register: (binding: ShortcutBinding) => () => void;\n /** Currently pending chord prefix (null if not in chord mode) */\n pending: Accessor<string | null>;\n /** Get all registered bindings */\n bindings: Accessor<ShortcutBinding[]>;\n}\n\nconst ShortcutContext = createContext<ShortcutContextValue>();\n\n/**\n * Parse a key string into normalized form\n */\nfunction normalizeKey(key: string): string {\n return key\n .toLowerCase()\n .split(\"+\")\n .sort((a, b) => {\n // Sort modifiers first: ctrl, alt, shift, then the key\n const order = [\"ctrl\", \"alt\", \"shift\"];\n const aIdx = order.indexOf(a);\n const bIdx = order.indexOf(b);\n if (aIdx !== -1 && bIdx !== -1) return aIdx - bIdx;\n if (aIdx !== -1) return -1;\n if (bIdx !== -1) return 1;\n return 0;\n })\n .join(\"+\");\n}\n\n/**\n * Check if a key event matches a key pattern\n */\nfunction matchesKey(\n event: { key: string; ctrl?: boolean; alt?: boolean; shift?: boolean },\n pattern: string,\n): boolean {\n const normalized = normalizeKey(pattern);\n const parts = normalized.split(\"+\");\n\n const key = parts.filter((p) => ![\"ctrl\", \"alt\", \"shift\"].includes(p))[0];\n const needsCtrl = parts.includes(\"ctrl\");\n const needsAlt = parts.includes(\"alt\");\n const needsShift = parts.includes(\"shift\");\n\n // Check modifiers\n if (needsCtrl && !event.ctrl) return false;\n if (needsAlt && !event.alt) return false;\n if (needsShift && !event.shift) return false;\n\n // Check key (case-insensitive)\n return event.key.toLowerCase() === key;\n}\n\n/**\n * Shortcut provider component\n */\nexport function ShortcutProvider(props: {\n bindings?: ShortcutBinding[];\n children: JSX.Element;\n}): JSX.Element {\n const [registeredBindings, setRegisteredBindings] = createSignal<ShortcutBinding[]>(\n props.bindings ?? [],\n );\n const [pending, setPending] = createSignal<string | null>(null);\n let chordTimeout: ReturnType<typeof setTimeout> | null = null;\n\n const register = (binding: ShortcutBinding): (() => void) => {\n setRegisteredBindings((prev) => [...prev, binding]);\n return () => {\n setRegisteredBindings((prev) => prev.filter((b) => b !== binding));\n };\n };\n // Exposed for testing or external integration\n const _handleKeyEvent_ = (event: {\n key: string;\n ctrl?: boolean;\n alt?: boolean;\n shift?: boolean;\n }) => {\n const bindings = registeredBindings();\n const currentPending = pending();\n\n // Clear chord timeout on any key\n if (chordTimeout) {\n clearTimeout(chordTimeout);\n chordTimeout = null;\n }\n\n // If we have a pending chord, look for the second part\n if (currentPending) {\n const fullChord = `${currentPending} ${event.key.toLowerCase()}`;\n const matchedBinding = bindings.find((b) => {\n const parts = b.key.toLowerCase().split(\" \");\n return parts.length === 2 && parts.join(\" \") === fullChord;\n });\n\n if (matchedBinding) {\n setPending(null);\n matchedBinding.action();\n return;\n }\n\n // No match, clear pending\n setPending(null);\n }\n\n // Check for simple shortcuts or chord starters\n for (const binding of bindings) {\n const parts = binding.key.toLowerCase().split(\" \");\n\n if (parts.length === 1) {\n // Simple shortcut\n if (matchesKey(event, parts[0])) {\n binding.action();\n return;\n }\n } else if (parts.length === 2) {\n // Chord starter\n if (matchesKey(event, parts[0])) {\n setPending(parts[0]);\n // Auto-cancel chord after 2 seconds\n chordTimeout = setTimeout(() => {\n setPending(null);\n }, 2000);\n return;\n }\n }\n }\n };\n\n // Note: OpenTUI handles global key events via the renderer\n // This context provides the registration API for components\n\n const value: ShortcutContextValue = {\n register,\n pending,\n bindings: registeredBindings,\n };\n\n return createComponent(ShortcutContext.Provider, {\n value,\n get children() {\n return props.children;\n },\n });\n}\n\n/**\n * Hook to access the shortcut context\n *\n * @returns Shortcut context value\n * @throws Error if used outside ShortcutProvider\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { register, pending } = useShortcuts()\n *\n * // Register a shortcut on mount\n * onMount(() => {\n * const cleanup = register({\n * key: \"ctrl+s\",\n * action: () => save(),\n * description: \"Save file\"\n * })\n * onCleanup(cleanup)\n * })\n *\n * return (\n * <text>\n * {pending() ? `Waiting for chord: ${pending()}...` : \"Ready\"}\n * </text>\n * )\n * }\n * ```\n */\nexport function useShortcuts(): ShortcutContextValue {\n const context = useContext(ShortcutContext);\n if (!context) {\n throw new Error(\"useShortcuts must be used within a ShortcutProvider\");\n }\n return context;\n}\n","/**\n * TUI Theme System\n *\n * Provides a reactive theme context with built-in themes and\n * support for custom theme registration.\n */\n\nimport { createContext, createSignal, useContext, type Accessor } from \"solid-js\";\nimport type { JSX } from \"@opentui/solid\";\nimport { createComponent } from \"@opentui/solid\";\nimport type { TuiTheme } from \"./types\";\n\nexport type { TuiTheme };\n\n/**\n * Built-in theme definitions\n */\nexport const TuiThemes: Record<string, TuiTheme> = {\n dark: {\n name: \"dark\",\n colors: {\n text: \"#ffffff\",\n muted: \"#888888\",\n background: \"#1a1a1a\",\n accent: \"#00d4ff\",\n success: \"#00ff88\",\n warning: \"#ffaa00\",\n error: \"#ff4444\",\n border: \"#444444\",\n selection: \"#0066cc\",\n },\n },\n light: {\n name: \"light\",\n colors: {\n text: \"#000000\", // Black text for readability\n muted: \"#333333\", // Dark gray muted\n background: \"#e8e8e8\", // Light gray background\n accent: \"#0044aa\", // Deep blue accent\n success: \"#005500\", // Dark green\n warning: \"#885500\", // Dark orange\n error: \"#880000\", // Dark red\n border: \"#888888\",\n selection: \"#0044aa\",\n },\n },\n monokai: {\n name: \"monokai\",\n colors: {\n text: \"#f8f8f2\",\n muted: \"#75715e\",\n background: \"#272822\",\n accent: \"#ae81ff\",\n success: \"#a6e22e\",\n warning: \"#e6db74\",\n error: \"#f92672\",\n border: \"#49483e\",\n selection: \"#49483e\",\n },\n },\n dracula: {\n name: \"dracula\",\n colors: {\n text: \"#f8f8f2\",\n muted: \"#6272a4\",\n background: \"#282a36\",\n accent: \"#bd93f9\",\n success: \"#50fa7b\",\n warning: \"#f1fa8c\",\n error: \"#ff5555\",\n border: \"#44475a\",\n selection: \"#44475a\",\n },\n },\n nord: {\n name: \"nord\",\n colors: {\n text: \"#eceff4\",\n muted: \"#4c566a\",\n background: \"#2e3440\",\n accent: \"#88c0d0\",\n success: \"#a3be8c\",\n warning: \"#ebcb8b\",\n error: \"#bf616a\",\n border: \"#3b4252\",\n selection: \"#4c566a\",\n },\n },\n solarized: {\n name: \"solarized\",\n colors: {\n text: \"#839496\",\n muted: \"#586e75\",\n background: \"#002b36\",\n accent: \"#268bd2\",\n success: \"#859900\",\n warning: \"#b58900\",\n error: \"#dc322f\",\n border: \"#073642\",\n selection: \"#073642\",\n },\n },\n};\n\n/** Shorthand alias for TuiThemes */\nexport const THEMES = TuiThemes;\n\n/**\n * Theme builder for creating custom themes by extending built-in presets.\n *\n * @example\n * ```ts\n * // Extend dark theme with custom background\n * const myTheme = Theme.from(THEMES.dark).extend({\n * name: \"my-dark\",\n * colors: { background: \"#1e1e1e\" }\n * });\n *\n * // Or create from scratch\n * const custom = Theme.create({\n * name: \"custom\",\n * colors: { text: \"#fff\", background: \"#000\", ... }\n * });\n * ```\n */\nexport const Theme = {\n /**\n * Start building a theme from an existing base theme.\n */\n from: (base: TuiTheme) => ({\n /**\n * Extend the base theme with overrides.\n * Color overrides are shallow-merged with the base colors.\n */\n extend: (overrides: { name?: string; colors?: Partial<TuiTheme[\"colors\"]> }): TuiTheme => ({\n name: overrides.name ?? `${base.name}-extended`,\n colors: { ...base.colors, ...overrides.colors },\n }),\n }),\n\n /**\n * Create a new theme from scratch.\n */\n create: (theme: TuiTheme): TuiTheme => theme,\n\n /**\n * Get all available theme names.\n */\n names: (): string[] => Object.keys(TuiThemes),\n\n /**\n * Get a theme by name, with fallback to dark theme.\n */\n get: (name: string): TuiTheme => TuiThemes[name] ?? TuiThemes[\"dark\"],\n};\n\n/**\n * Theme context value interface\n */\nexport interface ThemeContextValue {\n /** Current active theme */\n current: Accessor<TuiTheme>;\n /** Set theme by name */\n setTheme: (name: string) => void;\n /** Cycle to the next theme */\n cycle: () => void;\n /** Register a custom theme */\n register: (theme: TuiTheme) => void;\n /** Get all available theme names */\n names: () => string[];\n}\n\nconst ThemeContext = createContext<ThemeContextValue>();\n\n/**\n * Theme provider component\n */\nexport function ThemeProvider(props: { initial?: string; children: JSX.Element }): JSX.Element {\n const themes = { ...TuiThemes };\n const initialTheme = themes[props.initial ?? \"dark\"] ?? themes[\"dark\"];\n\n const [current, setCurrent] = createSignal<TuiTheme>(initialTheme);\n\n const setTheme = (name: string) => {\n if (themes[name]) {\n setCurrent(themes[name]);\n }\n };\n\n const cycle = () => {\n const currentName = current().name;\n const names = Object.keys(themes);\n const currentIndex = names.indexOf(currentName);\n const nextIndex = (currentIndex + 1) % names.length;\n setCurrent(themes[names[nextIndex]]);\n };\n\n const register = (theme: TuiTheme) => {\n themes[theme.name] = theme;\n };\n\n const names = () => Object.keys(themes);\n\n const value: ThemeContextValue = {\n current,\n setTheme,\n cycle,\n register,\n names,\n };\n\n // Using solid-js Context.Provider pattern\n return createComponent(ThemeContext.Provider, {\n value,\n get children() {\n return props.children;\n },\n });\n}\n\n/**\n * Hook to access the theme context\n *\n * @returns Theme context value\n * @throws Error if used outside ThemeProvider\n *\n * @example\n * ```tsx\n * function ThemedText() {\n * const { current, cycle } = useTheme()\n * return (\n * <text\n * style={{ fg: current().colors.accent }}\n * onKeyDown={(e) => e.key === \"t\" && cycle()}\n * >\n * Press T to cycle themes\n * </text>\n * )\n * }\n * ```\n */\nexport function useTheme(): ThemeContextValue {\n const context = useContext(ThemeContext);\n if (!context) {\n throw new Error(\"useTheme must be used within a ThemeProvider\");\n }\n return context;\n}\n","/**\n * TUI Toast Notification System\n *\n * Provides a simple overlay toast notification that fades in/out\n * for quick feedback messages like \"Copied!\", \"Saved\", etc.\n */\n\nimport { createContext, createSignal, useContext, type Accessor } from \"solid-js\";\nimport type { JSX } from \"@opentui/solid\";\nimport { createComponent } from \"@opentui/solid\";\nimport type { ToastType } from \"./types\";\n\nexport type { ToastType };\n\n/**\n * Internal toast state\n */\ninterface ToastState {\n message: string;\n type: ToastType;\n visible: boolean;\n}\n\n/**\n * Toast context value interface\n */\nexport interface ToastContextValue {\n /** Show an info toast */\n info: (message: string, duration?: number) => void;\n /** Show a success toast */\n success: (message: string, duration?: number) => void;\n /** Show an error toast */\n error: (message: string, duration?: number) => void;\n /** Show a warning toast */\n warning: (message: string, duration?: number) => void;\n /** Current toast state */\n state: Accessor<ToastState>;\n /** Hide the current toast */\n hide: () => void;\n}\n\nconst ToastContext = createContext<ToastContextValue>();\n\nconst DEFAULT_DURATION = 3000; // 3 seconds\n\n/**\n * Toast provider component\n *\n * Wraps your application to provide toast notification functionality.\n */\nexport function ToastProvider(props: { children: JSX.Element }): JSX.Element {\n const [state, setState] = createSignal<ToastState>({\n message: \"\",\n type: \"info\",\n visible: false,\n });\n\n let hideTimeout: ReturnType<typeof setTimeout> | null = null;\n\n const show = (message: string, type: ToastType, duration: number) => {\n // Clear any existing timeout\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n }\n\n // Show the toast\n setState({ message, type, visible: true });\n\n // Auto-hide after duration\n hideTimeout = setTimeout(() => {\n setState((prev) => ({ ...prev, visible: false }));\n }, duration);\n };\n\n const hide = () => {\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n hideTimeout = null;\n }\n setState((prev) => ({ ...prev, visible: false }));\n };\n\n const value: ToastContextValue = {\n info: (message, duration = DEFAULT_DURATION) => show(message, \"info\", duration),\n success: (message, duration = DEFAULT_DURATION) => show(message, \"success\", duration),\n error: (message, duration = DEFAULT_DURATION) => show(message, \"error\", duration),\n warning: (message, duration = DEFAULT_DURATION) => show(message, \"warning\", duration),\n state,\n hide,\n };\n\n return createComponent(ToastContext.Provider, {\n value,\n get children() {\n return props.children;\n },\n });\n}\n\n/**\n * Hook to access the toast context\n *\n * @returns Toast context value with show methods\n * @throws Error if used outside ToastProvider\n *\n * @example\n * ```tsx\n * function CopyButton() {\n * const toast = useToast()\n *\n * const handleCopy = async () => {\n * await navigator.clipboard.writeText(\"Hello!\")\n * toast.success(\"Copied to clipboard!\")\n * }\n *\n * return (\n * <button onMouseDown={handleCopy}>\n * Copy\n * </button>\n * )\n * }\n * ```\n */\nexport function useToast(): ToastContextValue {\n const context = useContext(ToastContext);\n if (!context) {\n throw new Error(\"useToast must be used within a ToastProvider\");\n }\n return context;\n}\n\n/**\n * Get the color for a toast type based on common theme conventions\n */\nexport function getToastColor(type: ToastType): string {\n switch (type) {\n case \"success\":\n return \"#00ff88\";\n case \"error\":\n return \"#ff4444\";\n case \"warning\":\n return \"#ffaa00\";\n case \"info\":\n default:\n return \"#00d4ff\";\n }\n}\n","/**\n * TTY Utilities\n *\n * Terminal cleanup and mouse support helpers.\n */\n\nimport type { Buffer } from \"node:buffer\";\n\n/**\n * Enable mouse wheel reporting in the terminal.\n * Call this in onMount().\n */\nexport function enableMouseReporting(): void {\n process.stdout.write(\"\\x1b[?1000h\"); // Enable X10 mouse mode\n process.stdout.write(\"\\x1b[?1006h\"); // Enable SGR extended mode\n}\n\n/**\n * Disable mouse reporting and restore terminal state.\n * Call this on cleanup/exit.\n */\nexport function disableMouseReporting(): void {\n process.stdout.write(\"\\x1b[?1000l\"); // Disable X10 mouse mode\n process.stdout.write(\"\\x1b[?1002l\"); // Disable button-event tracking\n process.stdout.write(\"\\x1b[?1003l\"); // Disable any-event tracking (mouse move)\n process.stdout.write(\"\\x1b[?1006l\"); // Disable SGR extended mode\n process.stdout.write(\"\\x1b[?1015l\"); // Disable urxvt extended mode\n}\n\n/**\n * Clear the terminal screen and scrollback buffer.\n */\nexport function clearScreen(): void {\n process.stdout.write(\"\\x1b[2J\\x1b[3J\\x1b[H\");\n}\n\n/**\n * Reset all terminal attributes (colors, bold, etc).\n */\nexport function resetAttributes(): void {\n process.stdout.write(\"\\x1b[0m\");\n}\n\n/**\n * Restore stdin to normal (non-raw) mode.\n */\nexport function restoreStdin(): void {\n if (process.stdin.isTTY && process.stdin.setRawMode) {\n try {\n process.stdin.setRawMode(false);\n } catch {\n // Ignore errors if stdin is already in normal mode\n }\n }\n}\n\n/**\n * Switch to alternate screen buffer.\n * Creates a new buffer for TUI applications.\n */\nexport function switchToAlternateScreen(): void {\n process.stdout.write(\"\\x1b[?1049h\");\n}\n\n/**\n * Switch back to main screen buffer.\n * Restores the terminal's original content.\n */\nexport function switchToMainScreen(): void {\n process.stdout.write(\"\\x1b[?1049l\");\n}\n\n/**\n * Complete terminal cleanup. Use as onDestroy callback.\n *\n * @example\n * ```tsx\n * createTuiApp(() => <App />, { onDestroy: cleanupTerminal });\n * ```\n */\nexport function cleanupTerminal(): void {\n switchToMainScreen();\n disableMouseReporting();\n clearScreen();\n resetAttributes();\n restoreStdin();\n}\n\n/**\n * Parse SGR mouse events from raw stdin data.\n * Returns scroll direction (-1 up, +1 down) or 0 if not a scroll event.\n */\nexport function parseMouseScroll(data: Buffer): number {\n const str = data.toString();\n // SGR mouse wheel: \\x1b[<64;X;YM (scroll up) or \\x1b[<65;X;YM (scroll down)\n const sgrMatch = str.match(/\\x1b\\[<(\\d+);(\\d+);(\\d+)([Mm])/);\n if (sgrMatch) {\n const button = parseInt(sgrMatch[1]!, 10);\n if (button === 64) return -1; // Scroll up\n if (button === 65) return 1; // Scroll down\n }\n return 0;\n}\n","/**\n * TUI Application Wrapper\n *\n * Provides a convenient entry point for creating TUI applications\n * with theme, shortcut, and toast support pre-configured.\n */\n\nimport { createComponent, render } from \"@opentui/solid\";\nimport type { JSX } from \"@opentui/solid\";\nimport { ExitGuard } from \"./runtime/ExitGuard\";\nimport { ShortcutProvider } from \"./shortcuts\";\nimport { ThemeProvider } from \"./themes\";\nimport { ToastProvider } from \"./toast\";\nimport { cleanupTerminal, enableMouseReporting, switchToAlternateScreen } from \"./tty\";\nimport type { TuiAppConfig, TuiTheme } from \"./types\";\n\nexport type { TuiAppConfig, TuiTheme };\n\n/**\n * Creates and renders a TUI application with all providers configured.\n *\n * @param App - Root component function\n * @param config - Application configuration\n * @returns Promise that resolves when the app is rendered\n *\n * @example\n * ```tsx\n * import { createTuiApp } from \"@alcyone-labs/arg-parser\"\n *\n * function MyApp() {\n * return (\n * <box>\n * <text>Hello World!</text>\n * </box>\n * )\n * }\n *\n * createTuiApp(() => <MyApp />, {\n * theme: \"monokai\",\n * shortcuts: [\n * { key: \"ctrl+t\", action: () => cycleTheme(), description: \"Cycle theme\" },\n * { key: \"ctrl+q\", action: () => process.exit(0), description: \"Quit\" }\n * ]\n * })\n * ```\n */\nexport function createTuiApp(App: () => JSX.Element, config: TuiAppConfig = {}): Promise<void> {\n const { theme = \"dark\", shortcuts = [], onDestroy } = config;\n\n switchToAlternateScreen();\n enableMouseReporting();\n\n return render(\n () =>\n createComponent(ExitGuard, {\n get children() {\n return createComponent(ThemeProvider, {\n get initial() {\n return theme;\n },\n get children() {\n return createComponent(ShortcutProvider, {\n get bindings() {\n return shortcuts;\n },\n get children() {\n return createComponent(ToastProvider, {\n get children() {\n return createComponent(App, {});\n },\n });\n },\n });\n },\n });\n },\n }),\n {\n onDestroy: () => {\n cleanupTerminal();\n onDestroy?.();\n },\n },\n );\n}\n","/**\n * TUI Provider\n *\n * Unified provider for TUI applications that handles:\n * - Theme context\n * - Shortcut bindings\n * - Toast notifications\n * - Mouse wheel events\n * - Terminal resize\n * - TTY cleanup on exit\n *\n * This is the recommended way to wrap TUI applications.\n */\n\nimport {\n createContext,\n createSignal,\n onCleanup,\n onMount,\n useContext,\n type Accessor,\n type JSX,\n} from \"solid-js\";\nimport type { MouseEvent } from \"@opentui/core\";\nimport { createComponent, useRenderer } from \"@opentui/solid\";\nimport { ExitGuard } from \"../runtime/ExitGuard\";\nimport { ShortcutProvider, type ShortcutBinding } from \"../shortcuts\";\nimport { ThemeProvider, type TuiTheme } from \"../themes\";\nimport { ToastProvider } from \"../toast\";\nimport { cleanupTerminal, enableMouseReporting, switchToAlternateScreen } from \"../tty\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface TuiContextValue {\n /** Current viewport height (rows) */\n viewportHeight: Accessor<number>;\n /** Current viewport width (columns) */\n viewportWidth: Accessor<number>;\n /** Exit the application gracefully */\n exit: (code?: number) => void;\n}\n\nexport interface TuiProviderProps {\n /** Theme name or custom theme object */\n theme?: string | TuiTheme;\n /** Keyboard shortcut bindings */\n shortcuts?: ShortcutBinding[];\n /** Callback when mouse wheel scrolls. Delta: negative=up, positive=down */\n onScroll?: (delta: number) => void;\n /** Scroll speed multiplier (default: 3 lines per tick) */\n scrollSpeed?: number;\n /** Reserved rows for calculating viewport (header, footer, etc) */\n reservedRows?: number;\n /** Children components */\n children: JSX.Element;\n}\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst TuiContext = createContext<TuiContextValue>();\n\n/**\n * Hook to access the TUI context.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { viewportHeight, exit } = useTui();\n * return <text>Height: {viewportHeight()}</text>;\n * }\n * ```\n */\nexport function useTui(): TuiContextValue {\n const context = useContext(TuiContext);\n if (!context) {\n throw new Error(\"useTui must be used within a TuiProvider\");\n }\n return context;\n}\n\n// ============================================================================\n// Provider Component\n// ============================================================================\n\n/**\n * Unified TUI Provider.\n *\n * Wraps your application with theme, shortcuts, toast, and mouse/resize handling.\n * Automatically cleans up TTY on exit.\n *\n * @example\n * ```tsx\n * import { TuiProvider, useTui, useTheme } from \"@alcyone-labs/arg-parser/tui\";\n *\n * function App() {\n * const { viewportHeight } = useTui();\n * const { current: theme } = useTheme();\n *\n * return (\n * <box backgroundColor={theme().colors.background}>\n * <text>Viewport: {viewportHeight()} rows</text>\n * </box>\n * );\n * }\n *\n * <TuiProvider\n * theme=\"dark\"\n * shortcuts={[{ key: \"q\", action: () => process.exit(0) }]}\n * onScroll={(delta) => console.log(\"Scrolled:\", delta)}\n * >\n * <App />\n * </TuiProvider>\n * ```\n */\nexport function TuiProvider(props: TuiProviderProps): JSX.Element {\n const renderer = useRenderer();\n const reservedRows = props.reservedRows ?? 8;\n const scrollSpeed = props.scrollSpeed ?? 3;\n\n // Viewport dimensions\n const [viewportHeight, setViewportHeight] = createSignal(\n Math.max(10, renderer.height - reservedRows),\n );\n const [viewportWidth, setViewportWidth] = createSignal(renderer.width);\n\n // Graceful exit\n const exit = (code = 0) => {\n process.exitCode = code;\n renderer.destroy();\n };\n\n // Resize handler\n const handleResize = (width: number, height: number) => {\n setViewportHeight(Math.max(10, height - reservedRows));\n setViewportWidth(width);\n };\n\n const handleMouseScroll = (event: MouseEvent) => {\n if (!props.onScroll || !event.scroll) {\n return;\n }\n\n const sign = event.scroll.direction === \"up\" ? -1 : event.scroll.direction === \"down\" ? 1 : 0;\n if (sign === 0) {\n return;\n }\n\n const delta = event.scroll.delta || 1;\n props.onScroll(sign * delta * scrollSpeed);\n };\n\n onMount(() => {\n switchToAlternateScreen();\n enableMouseReporting();\n renderer.on(\"resize\", handleResize);\n });\n\n onCleanup(() => {\n renderer.off(\"resize\", handleResize);\n cleanupTerminal();\n });\n\n // Context value\n const contextValue: TuiContextValue = {\n viewportHeight,\n viewportWidth,\n exit,\n };\n\n // Resolve theme\n const themeName = typeof props.theme === \"string\" ? props.theme : (props.theme?.name ?? \"dark\");\n\n // Build the provider tree\n return createComponent(ExitGuard, {\n get children() {\n return createComponent(TuiContext.Provider, {\n value: contextValue,\n get children() {\n return createComponent(ThemeProvider, {\n initial: themeName,\n get children() {\n return createComponent(ShortcutProvider, {\n get bindings() {\n return props.shortcuts ?? [];\n },\n get children() {\n return createComponent(ToastProvider, {\n get children() {\n return (\n <box width=\"100%\" height=\"100%\" onMouseScroll={handleMouseScroll}>\n {props.children}\n </box>\n );\n },\n });\n },\n });\n },\n });\n },\n });\n },\n });\n}\n","/**\n * Breadcrumb Component\n *\n * Displays a navigation path with separator icons.\n */\n\nimport { For } from \"solid-js\";\nimport type { JSX } from \"@opentui/solid\";\nimport { useTheme } from \"../themes\";\n\nexport interface BreadcrumbProps {\n /** Path segments to display */\n segments: string[];\n /** Separator character (default: \"›\") */\n separator?: string;\n /** Custom accent color (uses theme accent if not provided) */\n accentColor?: string;\n /** Custom muted color (uses theme muted if not provided) */\n mutedColor?: string;\n}\n\n/**\n * Breadcrumb navigation component.\n *\n * @example\n * ```tsx\n * <Breadcrumb segments={[\"Home\", \"Category\", selectedItem().name]} />\n * ```\n */\nexport function Breadcrumb(props: BreadcrumbProps): JSX.Element {\n const { current: theme } = useTheme();\n const separator = props.separator ?? \"›\";\n\n const accentColor = () => props.accentColor ?? theme().colors.accent;\n const mutedColor = () => props.mutedColor ?? theme().colors.muted;\n\n return (\n <box height={1} paddingLeft={2}>\n <For each={props.segments}>\n {(segment, idx) => (\n <>\n {idx() > 0 && <text color={mutedColor()}> {separator} </text>}\n <text color={accentColor()} bold>\n {segment}\n </text>\n </>\n )}\n </For>\n </box>\n );\n}\n","/**\n * Virtual List Component\n *\n * Renders a scrollable list with virtual rendering for performance.\n * Integrates with the framework's scroll and theme systems.\n */\n\nimport { createMemo, createSignal, For, Show } from \"solid-js\";\nimport type { Accessor, JSX } from \"@opentui/solid\";\nimport { useTheme } from \"../themes\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface VirtualListProps<T> {\n /** Array of items to render */\n items: T[] | Accessor<T[]>;\n /** Currently selected index */\n selectedIndex: number | Accessor<number>;\n /** Callback when selection changes */\n onSelect?: (index: number) => void;\n /** Viewport height in rows (if not using TuiProvider) */\n viewportHeight?: number | Accessor<number>;\n /** Title to display above the list */\n title?: string;\n /** Custom item renderer */\n renderItem?: (item: T, index: number, selected: boolean) => JSX.Element;\n /** Get label from item (used by default renderer) */\n getLabel?: (item: T) => string;\n /** Show selection indicator */\n showIndicator?: boolean;\n}\n\nexport interface VirtualListResult {\n /** Current scroll offset */\n scrollOffset: Accessor<number>;\n /** Adjust scroll to keep index visible */\n adjustScroll: (idx: number) => void;\n /** Scroll by delta */\n scrollBy: (delta: number) => void;\n /** Move selection up */\n selectPrevious: () => void;\n /** Move selection down */\n selectNext: () => void;\n}\n\n// ============================================================================\n// Helper to unwrap accessor or value\n// ============================================================================\n\nfunction unwrap<T>(value: T | Accessor<T>): T {\n return typeof value === \"function\" ? (value as Accessor<T>)() : value;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * Virtual List component with built-in scrolling.\n *\n * @example\n * ```tsx\n * <VirtualList\n * items={items}\n * selectedIndex={selectedIdx()}\n * onSelect={setSelectedIdx}\n * getLabel={(item) => item.name}\n * title=\"Items\"\n * />\n * ```\n */\nexport function VirtualList<T>(props: VirtualListProps<T>): JSX.Element {\n const { current: theme } = useTheme();\n const [scrollOffset, setScrollOffset] = createSignal(0);\n\n // Unwrap reactive props\n const items = () => unwrap(props.items);\n const selectedIndex = () => unwrap(props.selectedIndex);\n const viewportHeight = () => unwrap(props.viewportHeight ?? 20);\n const showIndicator = props.showIndicator ?? true;\n\n // Adjust scroll to keep selection visible\n const adjustScroll = (newIdx: number) => {\n const vh = viewportHeight();\n const currentOffset = scrollOffset();\n if (newIdx < currentOffset) {\n setScrollOffset(newIdx);\n } else if (newIdx >= currentOffset + vh) {\n setScrollOffset(newIdx - vh + 1);\n }\n };\n\n // Scroll by delta\n const scrollBy = (delta: number) => {\n const maxOffset = Math.max(0, items().length - viewportHeight());\n setScrollOffset((o) => Math.max(0, Math.min(maxOffset, o + delta)));\n };\n\n // Navigation helpers\n const selectPrevious = () => {\n if (props.onSelect) {\n const newIdx = Math.max(0, selectedIndex() - 1);\n props.onSelect(newIdx);\n adjustScroll(newIdx);\n }\n };\n\n const selectNext = () => {\n if (props.onSelect) {\n const newIdx = Math.min(items().length - 1, selectedIndex() + 1);\n props.onSelect(newIdx);\n adjustScroll(newIdx);\n }\n };\n\n // Visible items slice\n const visibleItems = createMemo(() => {\n const allItems = items();\n const vh = viewportHeight();\n const start = scrollOffset();\n const end = Math.min(start + vh, allItems.length);\n return allItems.slice(start, end).map((item, localIdx) => ({\n item,\n globalIndex: start + localIdx,\n }));\n });\n\n // Default item renderer\n const defaultRenderItem = (item: T, index: number, selected: boolean) => {\n const label = props.getLabel ? props.getLabel(item) : String(item);\n const t = theme();\n return (\n <box height={1} backgroundColor={selected ? t.colors.selection : undefined}>\n <text color={selected ? t.colors.background : t.colors.text}>\n {showIndicator ? (selected ? \"› \" : \" \") : \"\"}\n {label}\n </text>\n </box>\n );\n };\n\n const renderItem = props.renderItem ?? defaultRenderItem;\n\n return (\n <box flexDirection=\"column\" flexGrow={1}>\n <Show when={props.title}>\n <text bold color={theme().colors.text} marginBottom={1}>\n {props.title} ({selectedIndex() + 1}/{items().length})\n </text>\n </Show>\n <For each={visibleItems()}>\n {({ item, globalIndex }) => renderItem(item, globalIndex, globalIndex === selectedIndex())}\n </For>\n </box>\n );\n}\n\n/**\n * Hook to create a VirtualList controller for external navigation.\n */\nexport function createVirtualListController<T>(\n items: Accessor<T[]>,\n selectedIndex: Accessor<number>,\n setSelectedIndex: (idx: number) => void,\n viewportHeight: Accessor<number>,\n): VirtualListResult {\n const [scrollOffset, setScrollOffset] = createSignal(0);\n\n const adjustScroll = (newIdx: number) => {\n const vh = viewportHeight();\n const currentOffset = scrollOffset();\n if (newIdx < currentOffset) {\n setScrollOffset(newIdx);\n } else if (newIdx >= currentOffset + vh) {\n setScrollOffset(newIdx - vh + 1);\n }\n };\n\n const scrollBy = (delta: number) => {\n const maxOffset = Math.max(0, items().length - viewportHeight());\n setScrollOffset((o) => Math.max(0, Math.min(maxOffset, o + delta)));\n };\n\n const selectPrevious = () => {\n const newIdx = Math.max(0, selectedIndex() - 1);\n setSelectedIndex(newIdx);\n adjustScroll(newIdx);\n };\n\n const selectNext = () => {\n const newIdx = Math.min(items().length - 1, selectedIndex() + 1);\n setSelectedIndex(newIdx);\n adjustScroll(newIdx);\n };\n\n return { scrollOffset, adjustScroll, scrollBy, selectPrevious, selectNext };\n}\n","/**\n * Master Detail Layout Component\n *\n * A slot-based layout with:\n * - Header with title\n * - Breadcrumb navigation\n * - Left master panel (for list)\n * - Right detail panel (slot-based custom content)\n * - Footer with shortcuts\n */\n\nimport { Show } from \"solid-js\";\nimport type { JSX } from \"@opentui/solid\";\nimport { useTheme } from \"../themes\";\nimport { Breadcrumb } from \"./Breadcrumb\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface MasterDetailProps {\n /** Header title */\n header: string;\n /** Breadcrumb segments (optional) */\n breadcrumb?: string[];\n /** Footer text (shortcuts hint) */\n footer?: string;\n /** Master panel content (left side - typically VirtualList) */\n master: JSX.Element;\n /** Detail panel content (right side - custom slot) */\n detail: JSX.Element;\n /** Master panel width (default: \"35%\") */\n masterWidth?: string;\n /** Header icon emoji (optional) */\n headerIcon?: string;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * Master-Detail layout with slot-based panels.\n *\n * @example\n * ```tsx\n * <MasterDetail\n * header=\"My App\"\n * headerIcon=\"📋\"\n * breadcrumb={[\"Items\", selectedItem().name]}\n * footer=\"↑↓: Navigate | Enter: Select | q: Quit\"\n * master={\n * <VirtualList\n * items={items}\n * selectedIndex={selectedIdx()}\n * onSelect={setSelectedIdx}\n * getLabel={(item) => item.name}\n * />\n * }\n * detail={\n * <ItemDetails item={selectedItem()} />\n * }\n * />\n * ```\n */\nexport function MasterDetail(props: MasterDetailProps): JSX.Element {\n const { current: theme } = useTheme();\n const masterWidth = props.masterWidth ?? \"35%\";\n\n return (\n <box\n width=\"100%\"\n height=\"100%\"\n flexDirection=\"column\"\n backgroundColor={theme().colors.background}\n >\n {/* Header */}\n <box\n height={3}\n borderStyle=\"single\"\n borderColor={theme().colors.accent}\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n <text bold color={theme().colors.accent}>\n {props.headerIcon ? ` ${props.headerIcon} ` : \" \"}\n {props.header}{\" \"}\n </text>\n </box>\n\n {/* Breadcrumb */}\n <Show when={props.breadcrumb && props.breadcrumb.length > 0}>\n <Breadcrumb segments={props.breadcrumb!} />\n </Show>\n\n {/* Main content area */}\n <box flexGrow={1} flexDirection=\"row\">\n {/* Master Panel (left) */}\n <box\n width={masterWidth}\n borderStyle=\"single\"\n borderColor={theme().colors.border}\n flexDirection=\"column\"\n padding={1}\n >\n {props.master}\n </box>\n\n {/* Detail Panel (right - slot) */}\n <box\n flexGrow={1}\n borderStyle=\"single\"\n borderColor={theme().colors.border}\n flexDirection=\"column\"\n padding={2}\n >\n {props.detail}\n </box>\n </box>\n\n {/* Footer */}\n <Show when={props.footer}>\n <box height={1} backgroundColor={theme().colors.background}>\n <text color={theme().colors.muted}> {props.footer}</text>\n </box>\n </Show>\n </box>\n );\n}\n","/**\n * MasterDetailLayout Component\n *\n * A split-pane layout with a master list on the left and\n * detail view on the right. Both panes scroll independently.\n */\n\nimport type { JSX } from \"solid-js\";\n\n/**\n * Props for MasterDetailLayout\n */\nexport interface MasterDetailLayoutProps {\n /** Width of the master panel (number = columns, string = percentage like \"30%\") */\n masterWidth?: number | string;\n /** Master panel content (typically a list) */\n master: JSX.Element;\n /** Detail panel content */\n detail: JSX.Element;\n /** Gap between panels (default: 1) */\n gap?: number;\n /** Whether to show a vertical divider (default: true) */\n showDivider?: boolean;\n}\n\n/**\n * Parse width prop to a flexBasis value\n */\nfunction parseWidth(width: number | string | undefined): number | string {\n if (width === undefined) return \"30%\";\n if (typeof width === \"number\") return width;\n if (width.endsWith(\"%\")) {\n const percent = parseInt(width.replace(\"%\", \"\"), 10);\n return `${percent}%`;\n }\n return width;\n}\n\n/**\n * MasterDetailLayout - Split panel layout with independent scrolling\n *\n * @example\n * ```tsx\n * <MasterDetailLayout\n * masterWidth={30}\n * master={<ItemList items={items} onSelect={setSelected} />}\n * detail={<DetailView item={selected()} />}\n * />\n * ```\n */\nexport function MasterDetailLayout(props: MasterDetailLayoutProps): JSX.Element {\n const masterWidth = parseWidth(props.masterWidth);\n const gap = props.gap ?? 1;\n const showDivider = props.showDivider ?? true;\n\n // Build the layout using OpenTUI's box elements with Yoga flexbox\n // This is a conceptual implementation - actual element names depend on @opentui/solid catalog\n\n return {\n type: \"box\",\n props: {\n flexDirection: \"row\",\n width: \"100%\",\n height: \"100%\",\n },\n children: [\n // Master panel\n {\n type: \"box\",\n props: {\n flexBasis: masterWidth,\n flexShrink: 0,\n overflow: \"scroll\",\n },\n children: props.master,\n },\n // Divider (optional)\n ...(showDivider\n ? [\n {\n type: \"box\",\n props: {\n width: 1,\n marginLeft: Math.floor(gap / 2),\n marginRight: Math.ceil(gap / 2),\n },\n children: {\n type: \"text\",\n props: {\n style: { fg: \"#444444\" },\n },\n children: \"│\".repeat(100), // Repeating for height\n },\n },\n ]\n : []),\n // Detail panel\n {\n type: \"box\",\n props: {\n flexGrow: 1,\n overflow: \"scroll\",\n },\n children: props.detail,\n },\n ],\n } as unknown as JSX.Element;\n}\n\nexport default MasterDetailLayout;\n","/**\n * DrillDownNavigator Component\n *\n * Stack-based navigation for drilling into nested views.\n * Supports back navigation with Esc or Left Arrow.\n */\n\nimport { createSignal, type Accessor, type JSX } from \"solid-js\";\n\n/**\n * Navigation API passed to children\n */\nexport interface NavigatorApi {\n /** Push a new view onto the stack */\n push: (view: () => JSX.Element) => void;\n /** Pop the current view and go back */\n pop: () => void;\n /** Replace the current view */\n replace: (view: () => JSX.Element) => void;\n /** Go back to the root view */\n reset: () => void;\n /** Current stack depth */\n depth: Accessor<number>;\n /** Whether we can go back */\n canGoBack: Accessor<boolean>;\n}\n\n/**\n * Props for DrillDownNavigator\n */\nexport interface DrillDownNavigatorProps {\n /** Render function receiving navigator API */\n children: (nav: NavigatorApi) => JSX.Element;\n /** Called when navigation stack changes */\n onNavigate?: (depth: number) => void;\n}\n\n/**\n * DrillDownNavigator - Stack-based drill-down navigation\n *\n * @example\n * ```tsx\n * <DrillDownNavigator>\n * {(nav) => (\n * <FileList\n * onSelect={(file) => nav.push(() => <TraceList file={file} />)}\n * />\n * )}\n * </DrillDownNavigator>\n * ```\n */\nexport function DrillDownNavigator(props: DrillDownNavigatorProps): JSX.Element {\n const [stack, setStack] = createSignal<Array<() => JSX.Element>>([]);\n\n const push = (view: () => JSX.Element) => {\n setStack((prev) => [...prev, view]);\n props.onNavigate?.(stack().length + 1);\n };\n\n const pop = () => {\n if (stack().length > 0) {\n setStack((prev) => prev.slice(0, -1));\n props.onNavigate?.(stack().length - 1);\n }\n };\n\n const replace = (view: () => JSX.Element) => {\n if (stack().length > 0) {\n setStack((prev) => [...prev.slice(0, -1), view]);\n } else {\n push(view);\n }\n };\n\n const reset = () => {\n setStack([]);\n props.onNavigate?.(0);\n };\n\n const depth = () => stack().length;\n const canGoBack = () => stack().length > 0;\n\n const api: NavigatorApi = {\n push,\n pop,\n replace,\n reset,\n depth,\n canGoBack,\n };\n\n // Render the current view (top of stack) or the initial children\n const currentView = (): JSX.Element => {\n const currentStack = stack();\n if (currentStack.length > 0) {\n return currentStack[currentStack.length - 1]();\n }\n return props.children(api);\n };\n\n // Wrap with key handler for back navigation\n return {\n type: \"box\",\n props: {\n width: \"100%\",\n height: \"100%\",\n onKeyDown: (event: { key: string; defaultPrevented?: boolean }) => {\n if (event.defaultPrevented) return;\n\n // Escape or Left Arrow to go back\n if ((event.key === \"Escape\" || event.key === \"ArrowLeft\") && canGoBack()) {\n pop();\n }\n },\n },\n children: currentView(),\n } as unknown as JSX.Element;\n}\n\nexport default DrillDownNavigator;\n","/**\n * Card and StatCard Components\n *\n * Dashboard-style card components for displaying information\n * and statistics with borders and optional interactivity.\n */\n\nimport type { JSX } from \"@opentui/solid\";\nimport { useTheme } from \"../themes\";\n\n/**\n * Props for Card component\n */\nexport interface CardProps {\n /** Card title (displayed in top border) */\n title?: string;\n /** Card content */\n children: JSX.Element;\n /** Click handler for interactive cards */\n onClick?: () => void;\n /** Border style (default: \"single\") */\n borderStyle?: \"single\" | \"double\" | \"rounded\" | \"none\";\n /** Custom border color */\n borderColor?: string;\n /** Padding inside the card (default: 1) */\n padding?: number;\n /** Width of the card */\n width?: number | string;\n /** Height of the card */\n height?: number | string;\n}\n\n/**\n * Box drawing characters for different border styles\n * @internal Reserved for future use with custom border rendering\n */\nconst _BorderChars_ = {\n single: { tl: \"┌\", tr: \"┐\", bl: \"└\", br: \"┘\", h: \"─\", v: \"│\" },\n double: { tl: \"╔\", tr: \"╗\", bl: \"╚\", br: \"╝\", h: \"═\", v: \"║\" },\n rounded: { tl: \"╭\", tr: \"╮\", bl: \"╰\", br: \"╯\", h: \"─\", v: \"│\" },\n none: { tl: \" \", tr: \" \", bl: \" \", br: \" \", h: \" \", v: \" \" },\n};\n\n/**\n * Card - A bordered container for content\n *\n * @example\n * ```tsx\n * <Card title=\"Statistics\" onClick={() => showDetails()}>\n * <text>Total Items: 42</text>\n * <text>Active: 38</text>\n * </Card>\n * ```\n */\nexport function Card(props: CardProps): JSX.Element {\n const borderStyle = props.borderStyle ?? \"single\";\n const padding = props.padding ?? 1;\n\n // Get border color from theme or props\n let borderColor = props.borderColor;\n if (!borderColor) {\n try {\n const { current } = useTheme();\n borderColor = current().colors.border;\n } catch {\n borderColor = \"#444444\"; // Fallback\n }\n }\n\n return {\n type: \"box\",\n props: {\n flexDirection: \"column\",\n width: props.width,\n height: props.height,\n ...(props.onClick && { onMouseDown: props.onClick }),\n style: {\n border: borderStyle !== \"none\" ? borderStyle : undefined,\n borderColor,\n padding,\n },\n },\n children: [\n // Title row (if provided)\n ...(props.title\n ? [\n {\n type: \"text\",\n props: {\n style: { bold: true },\n },\n children: ` ${props.title} `,\n },\n ]\n : []),\n // Content\n props.children,\n ],\n } as unknown as JSX.Element;\n}\n\n/**\n * Props for StatCard component\n */\nexport interface StatCardProps {\n /** Label describing the statistic */\n label: string;\n /** Numeric or string value */\n value: number | string;\n /** Format for numeric values: \"number\", \"compact\", \"percent\", \"currency\" */\n format?: \"number\" | \"compact\" | \"percent\" | \"currency\";\n /** Currency code for \"currency\" format (default: \"USD\") */\n currency?: string;\n /** Trend indicator: \"up\", \"down\", \"neutral\" */\n trend?: \"up\" | \"down\" | \"neutral\";\n /** Previous value for trend calculation */\n previousValue?: number;\n /** Click handler */\n onClick?: () => void;\n /** Width of the card */\n width?: number | string;\n}\n\n/**\n * Format a number according to the specified format\n */\nfunction formatValue(\n value: number | string,\n format: StatCardProps[\"format\"],\n currency?: string,\n): string {\n if (typeof value === \"string\") return value;\n\n switch (format) {\n case \"compact\":\n if (value >= 1_000_000_000) return `${(value / 1_000_000_000).toFixed(1)}B`;\n if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M`;\n if (value >= 1_000) return `${(value / 1_000).toFixed(1)}K`;\n return value.toString();\n case \"percent\":\n return `${(value * 100).toFixed(1)}%`;\n case \"currency\":\n return new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: currency ?? \"USD\",\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n }).format(value);\n case \"number\":\n default:\n return new Intl.NumberFormat(\"en-US\").format(value);\n }\n}\n\n/**\n * Get trend emoji and color\n */\nfunction getTrendIndicator(trend: StatCardProps[\"trend\"]): {\n symbol: string;\n color: string;\n} {\n switch (trend) {\n case \"up\":\n return { symbol: \"▲\", color: \"#00ff88\" };\n case \"down\":\n return { symbol: \"▼\", color: \"#ff4444\" };\n case \"neutral\":\n default:\n return { symbol: \"─\", color: \"#888888\" };\n }\n}\n\n/**\n * StatCard - A card for displaying a single statistic\n *\n * @example\n * ```tsx\n * <StatCard\n * label=\"Total Tokens\"\n * value={1234567}\n * format=\"compact\"\n * trend=\"up\"\n * />\n * // Displays: \"Total Tokens: 1.2M ▲\"\n * ```\n */\nexport function StatCard(props: StatCardProps): JSX.Element {\n const formattedValue = formatValue(props.value, props.format ?? \"number\", props.currency);\n\n const trendIndicator = props.trend ? getTrendIndicator(props.trend) : null;\n\n return {\n type: \"box\",\n props: {\n flexDirection: \"column\",\n width: props.width,\n padding: 1,\n style: {\n border: \"single\",\n },\n ...(props.onClick && { onMouseDown: props.onClick }),\n },\n children: [\n // Label\n {\n type: \"text\",\n props: {\n style: { fg: \"#888888\" },\n },\n children: props.label,\n },\n // Value with optional trend\n {\n type: \"box\",\n props: {\n flexDirection: \"row\",\n gap: 1,\n },\n children: [\n {\n type: \"text\",\n props: {\n style: { bold: true, fg: \"#ffffff\" },\n },\n children: formattedValue,\n },\n ...(trendIndicator\n ? [\n {\n type: \"text\",\n props: {\n style: { fg: trendIndicator.color },\n },\n children: trendIndicator.symbol,\n },\n ]\n : []),\n ],\n },\n ],\n } as unknown as JSX.Element;\n}\n\nexport default Card;\n","/**\n * MarkdownBlock Component\n *\n * Renders markdown content using simple text formatting.\n * Currently supports basic text rendering with theme colors.\n * Future improvements could add proper markdown parsing and syntax highlighting.\n */\n\nimport type { JSX } from \"solid-js\";\nimport { useTheme } from \"../themes\";\n\nexport interface MarkdownBlockProps {\n /** Markdown content string */\n content: string;\n /** Width */\n width?: number | string;\n /** Height */\n height?: number | string;\n /** Padding */\n padding?: number;\n}\n\n/**\n * MarkdownBlock - Renders markdown text\n *\n * @example\n * ```tsx\n * <MarkdownBlock\n * content=\"# Hello wold\\n\\nThis is **markdown**.\"\n * />\n * ```\n */\nexport function MarkdownBlock(props: MarkdownBlockProps): JSX.Element {\n const { current } = useTheme();\n\n // TODO: Add proper markdown parsing integration (e.g. marked-terminal or similar)\n // For now, we simply render the text with the theme's text color.\n\n return {\n type: \"box\",\n props: {\n flexDirection: \"column\",\n width: props.width ?? \"100%\",\n height: props.height,\n padding: props.padding ?? 0,\n overflow: \"scroll\",\n },\n children: [\n {\n type: \"text\",\n props: {\n style: {\n fg: current().colors.text,\n },\n text: props.content,\n },\n },\n ],\n } as unknown as JSX.Element;\n}\n\nexport default MarkdownBlock;\n","/**\n * Button Component\n *\n * A clickable button with hover and active states.\n */\n\nimport { createSignal, type JSX } from \"solid-js\";\nimport { useTheme } from \"../themes\";\n\nexport interface ButtonProps {\n /** Button label */\n label: string;\n /** Click handler */\n onClick?: () => void;\n /** Width (auto if not specified) */\n width?: number | string;\n /** Disabled state */\n disabled?: boolean;\n /** Primary button style variant */\n variant?: \"primary\" | \"secondary\" | \"danger\";\n}\n\n/**\n * Button - interactive clickable element\n *\n * @example\n * ```tsx\n * <Button label=\"Submit\" onClick={handleSubmit} variant=\"primary\" />\n * ```\n */\nexport function Button(props: ButtonProps): JSX.Element {\n const { current } = useTheme();\n const [isHovered, setIsHovered] = createSignal(false);\n const [isPressed, setIsPressed] = createSignal(false);\n\n // Derived styles based on state\n const getBackgroundColor = () => {\n if (props.disabled) return current().colors.muted;\n\n switch (props.variant) {\n case \"danger\":\n return isPressed() ? \"#bd2c00\" : isHovered() ? \"#c82829\" : current().colors.error;\n case \"primary\":\n default:\n // Use accent color for primary, but darken/lighten on interaction\n // Note: OpenTUI colors are singular strings, real color manipulation would need a helper.\n // For now relying on simple swaps or static mappings could be better,\n // but let's just stick to theme colors.\n return isPressed()\n ? current().colors.selection\n : isHovered()\n ? current().colors.accent\n : current().colors.accent;\n }\n };\n\n const getTextColor = () => {\n if (props.disabled) return current().colors.background;\n return props.variant === \"primary\" || props.variant === \"danger\"\n ? \"#ffffff\"\n : current().colors.text;\n };\n\n return {\n type: \"box\",\n props: {\n width: props.width,\n height: 3, // Standard button height with border\n flexDirection: \"row\",\n alignItems: \"center\",\n justifyContent: \"center\",\n style: {\n border: \"single\",\n borderColor:\n isHovered() && !props.disabled ? current().colors.text : current().colors.border,\n bg: getBackgroundColor(),\n },\n // Event handlers\n onMouseOver: () => !props.disabled && setIsHovered(true),\n onMouseOut: () => {\n setIsHovered(false);\n setIsPressed(false);\n },\n onMouseDown: () => !props.disabled && setIsPressed(true),\n onMouseUp: () => {\n if (!props.disabled && isPressed()) {\n setIsPressed(false);\n props.onClick?.();\n }\n },\n },\n children: [\n {\n type: \"text\",\n props: {\n style: {\n fg: getTextColor(),\n bold: true,\n },\n text: ` ${props.label} `,\n },\n },\n ],\n } as unknown as JSX.Element;\n}\n\nexport default Button;\n","/**\n * Master-Detail Layout\n *\n * A 3-fold TUI layout template with:\n * - Header (with title)\n * - Breadcrumb navigation\n * - Master panel (left, scrollable list)\n * - Detail panel (right, content area)\n * - Footer (shortcuts hint)\n *\n * @example\n * ```tsx\n * <MasterDetailLayout\n * header=\"My App\"\n * breadcrumb={[\"Home\", selectedItem().name]}\n * footer=\"q: Quit | t: Theme\"\n * theme={currentTheme()}\n * >\n * <MasterPanel>\n * <For each={items()}>\n * {(item) => <ListItem {...item} />}\n * </For>\n * </MasterPanel>\n * <DetailPanel>\n * <ItemDetails item={selectedItem()} />\n * </DetailPanel>\n * </MasterDetailLayout>\n * ```\n */\n\nimport type { JSX } from \"@opentui/solid\";\nimport type { TuiTheme } from \"../types\";\n\n// ============================================================================\n// Theme Presets\n// ============================================================================\n\nexport const LAYOUT_THEMES = {\n dark: {\n bg: \"#0d0d0d\",\n fg: \"#f5f5f5\",\n accent: \"#00d4ff\",\n muted: \"#999999\",\n error: \"#ff4444\",\n success: \"#44ff44\",\n border: \"#444444\",\n selection: \"#00d4ff\",\n selectionFg: \"#000000\",\n },\n light: {\n bg: \"#e8e8e8\",\n fg: \"#000000\",\n accent: \"#0044aa\",\n muted: \"#333333\",\n error: \"#880000\",\n success: \"#005500\",\n border: \"#888888\",\n selection: \"#0044aa\",\n selectionFg: \"#ffffff\",\n },\n monokai: {\n bg: \"#272822\",\n fg: \"#f8f8f2\",\n accent: \"#a6e22e\",\n muted: \"#75715e\",\n error: \"#f92672\",\n success: \"#a6e22e\",\n border: \"#49483e\",\n selection: \"#a6e22e\",\n selectionFg: \"#272822\",\n },\n} as const;\n\nexport type LayoutThemeName = keyof typeof LAYOUT_THEMES;\nexport type LayoutTheme = (typeof LAYOUT_THEMES)[LayoutThemeName];\n\n// ============================================================================\n// Layout Props\n// ============================================================================\n\nexport interface MasterDetailLayoutProps {\n /** Header title text */\n header: string;\n /** Breadcrumb path segments (e.g., [\"Home\", \"Category\", \"Item\"]) */\n breadcrumb?: string[];\n /** Footer text (shortcuts hint) */\n footer?: string;\n /** Theme object or theme name */\n theme?: LayoutTheme | LayoutThemeName;\n /** Master panel width (default: \"35%\") */\n masterWidth?: string;\n /** Children should be MasterPanel and DetailPanel */\n children: JSX.Element;\n}\n\nexport interface PanelProps {\n children: JSX.Element;\n}\n\n// ============================================================================\n// Helper to resolve theme\n// ============================================================================\n\nfunction resolveTheme(theme?: LayoutTheme | LayoutThemeName): LayoutTheme {\n if (!theme) return LAYOUT_THEMES.dark;\n if (typeof theme === \"string\") return LAYOUT_THEMES[theme] ?? LAYOUT_THEMES.dark;\n return theme;\n}\n\n// ============================================================================\n// Components (as functions returning JSX)\n// ============================================================================\n\n/**\n * Main layout wrapper.\n */\nexport function MasterDetailLayout(props: MasterDetailLayoutProps): JSX.Element {\n const t = resolveTheme(props.theme);\n const masterWidth = props.masterWidth ?? \"35%\";\n\n return (\n <box width=\"100%\" height=\"100%\" flexDirection=\"column\" backgroundColor={t.bg}>\n {/* Header */}\n <box\n height={3}\n borderStyle=\"single\"\n borderColor={t.accent}\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n <text bold color={t.accent}>\n {\" \"}\n {props.header}{\" \"}\n </text>\n </box>\n\n {/* Breadcrumb */}\n {props.breadcrumb && props.breadcrumb.length > 0 && (\n <box height={1} paddingLeft={2} backgroundColor={t.bg}>\n {props.breadcrumb.map((segment, idx) => (\n <>\n {idx > 0 && <text color={t.muted}> › </text>}\n <text color={t.accent} bold>\n {segment}\n </text>\n </>\n ))}\n </box>\n )}\n\n {/* Main content area */}\n <box flexGrow={1} flexDirection=\"row\">\n {props.children}\n </box>\n\n {/* Footer */}\n {props.footer && (\n <box height={1} backgroundColor={t.bg}>\n <text color={t.muted}> {props.footer}</text>\n </box>\n )}\n </box>\n );\n}\n\n/**\n * Left panel for the master list.\n */\nexport function MasterPanel(\n props: PanelProps & {\n theme?: LayoutTheme | LayoutThemeName;\n width?: string;\n },\n): JSX.Element {\n const t = resolveTheme(props.theme);\n return (\n <box\n width={props.width ?? \"35%\"}\n borderStyle=\"single\"\n borderColor={t.border}\n flexDirection=\"column\"\n padding={1}\n >\n {props.children}\n </box>\n );\n}\n\n/**\n * Right panel for detail content.\n */\nexport function DetailPanel(\n props: PanelProps & {\n theme?: LayoutTheme | LayoutThemeName;\n },\n): JSX.Element {\n const t = resolveTheme(props.theme);\n return (\n <box\n flexGrow={1}\n borderStyle=\"single\"\n borderColor={t.border}\n flexDirection=\"column\"\n padding={2}\n >\n {props.children}\n </box>\n );\n}\n\n/**\n * A list item component for use in MasterPanel.\n */\nexport function ListItem(props: {\n label: string;\n selected?: boolean;\n theme?: LayoutTheme | LayoutThemeName;\n}): JSX.Element {\n const t = resolveTheme(props.theme);\n return (\n <box height={1} backgroundColor={props.selected ? t.selection : undefined}>\n <text color={props.selected ? t.selectionFg : t.fg}>\n {props.selected ? \"› \" : \" \"}\n {props.label}\n </text>\n </box>\n );\n}\n","/**\n * Virtual Scroll Hook\n *\n * Manages a virtualized list with a fixed viewport height.\n */\n\nimport { createMemo, createSignal, type Accessor } from \"solid-js\";\n\nexport interface VirtualScrollResult<T> {\n /** Items currently visible in the viewport */\n visibleItems: Accessor<Array<{ item: T; globalIndex: number }>>;\n /** Current scroll offset (first visible item index) */\n scrollOffset: Accessor<number>;\n /** Adjust scroll to keep the given index visible */\n adjustScroll: (idx: number) => void;\n /** Scroll by a delta (for mouse wheel) */\n scrollBy: (delta: number) => void;\n}\n\n/**\n * Create a virtual scroll controller for a list.\n *\n * @param items - Accessor returning the full list of items\n * @param selectedIdx - Accessor returning the currently selected index\n * @param viewportHeight - Accessor returning the viewport height in rows\n * @returns VirtualScrollResult with visible items and scroll controls\n *\n * @example\n * ```tsx\n * const scroll = useVirtualScroll(\n * () => myItems,\n * selectedIdx,\n * () => Math.max(10, process.stdout.rows - 8)\n * );\n *\n * <For each={scroll.visibleItems()}>\n * {({ item, globalIndex }) => ...}\n * </For>\n * ```\n */\nexport function useVirtualScroll<T>(\n items: Accessor<T[]>,\n _selectedIdx: Accessor<number>,\n viewportHeight: Accessor<number>,\n): VirtualScrollResult<T> {\n const [scrollOffset, setScrollOffset] = createSignal(0);\n\n const adjustScroll = (newIdx: number) => {\n const vh = viewportHeight();\n const currentOffset = scrollOffset();\n if (newIdx < currentOffset) {\n setScrollOffset(newIdx);\n } else if (newIdx >= currentOffset + vh) {\n setScrollOffset(newIdx - vh + 1);\n }\n };\n\n const visibleItems = createMemo(() => {\n const allItems = items();\n const vh = viewportHeight();\n const start = scrollOffset();\n const end = Math.min(start + vh, allItems.length);\n return allItems.slice(start, end).map((item, localIdx) => ({\n item,\n globalIndex: start + localIdx,\n }));\n });\n\n const scrollBy = (delta: number) => {\n const maxOffset = Math.max(0, items().length - viewportHeight());\n setScrollOffset((o) => Math.max(0, Math.min(maxOffset, o + delta)));\n };\n\n return { visibleItems, adjustScroll, scrollOffset, scrollBy };\n}\n\n/**\n * Get dynamic viewport height based on terminal size.\n *\n * @param reservedRows - Number of rows reserved for header/footer/etc (default: 8)\n * @param minHeight - Minimum viewport height (default: 10)\n */\nexport function getViewportHeight(reservedRows = 8, minHeight = 10): number {\n return Math.max(minHeight, (process.stdout.rows || 24) - reservedRows);\n}\n","/**\n * Mouse Hook\n *\n * Enables mouse wheel detection for TUI applications.\n */\n\nimport { onCleanup, onMount } from \"solid-js\";\nimport { disableMouseReporting, enableMouseReporting, parseMouseScroll } from \"../tty\";\n\nexport interface UseMouseOptions {\n /** Callback when mouse wheel scrolls. Delta is negative for up, positive for down. */\n onScroll?: (delta: number) => void;\n /** Scroll speed multiplier (default: 3 lines per tick) */\n scrollSpeed?: number;\n}\n\n/**\n * Enable mouse wheel support in a TUI component.\n *\n * Automatically enables mouse reporting on mount and cleans up on unmount.\n *\n * @example\n * ```tsx\n * function App() {\n * const [idx, setIdx] = createSignal(0);\n *\n * useMouse({\n * onScroll: (delta) => setIdx(i => Math.max(0, i + delta))\n * });\n *\n * return <box>...</box>;\n * }\n * ```\n */\nexport function useMouse(options: UseMouseOptions = {}): void {\n const { onScroll, scrollSpeed = 3 } = options;\n\n const handleInput = (data: Buffer) => {\n const scrollDir = parseMouseScroll(data);\n if (scrollDir !== 0 && onScroll) {\n onScroll(scrollDir * scrollSpeed);\n }\n };\n\n onMount(() => {\n enableMouseReporting();\n\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n }\n process.stdin.on(\"data\", handleInput);\n });\n\n onCleanup(() => {\n disableMouseReporting();\n process.stdin.off(\"data\", handleInput);\n });\n}\n"],"mappings":"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"}
|