import { Command } from '../commands' import { PRODUCT_COMMAND, PRODUCT_NAME } from '../constants/product' import { getCustomCommandDirectories, hasCustomCommands, type CustomCommandWithScope, } from '../services/customCommands' import * as React from 'react' import { Box, Text, useInput } from 'ink' import { getTheme } from '../utils/theme' import { PressEnterToContinue } from './PressEnterToContinue' import { MACRO } from '../constants/macros' /** * Help Component - Interactive help system with progressive disclosure * * This component provides a comprehensive help interface that progressively * reveals information to avoid overwhelming users. It categorizes commands * into built-in and custom types, providing clear guidance on usage. * * The progressive disclosure pattern (count-based) ensures users can absorb * information at their own pace while maintaining a responsive interface. */ export function Help({ commands, onClose, }: { commands: Command[] onClose: () => void }): React.ReactNode { const theme = getTheme() const moreHelp = `Learn more at: ${MACRO.README_URL}` // Filter out hidden commands from the help display const filteredCommands = commands.filter(cmd => !cmd.isHidden) // Separate built-in commands from custom commands // Built-in commands are those that don't follow the custom command patterns const builtInCommands = filteredCommands.filter( cmd => !cmd.name.startsWith('project:') && !cmd.name.startsWith('user:'), ) // Custom commands are those with project: or user: prefixes const customCommands = filteredCommands.filter( cmd => cmd.name.startsWith('project:') || cmd.name.startsWith('user:'), ) as CustomCommandWithScope[] // Progressive disclosure state for managing information flow const [count, setCount] = React.useState(0) // Timer-based progressive disclosure to prevent information overload React.useEffect(() => { const timer = setTimeout(() => { if (count < 3) { setCount(count + 1) } }, 250) return () => clearTimeout(timer) }, [count]) // Handle Enter key to close help useInput((_, key) => { if (key.return) onClose() }) return ( {`${PRODUCT_NAME} v${MACRO.VERSION}`} {PRODUCT_NAME} is a beta research preview. Always review{' '} {PRODUCT_NAME}'s responses, especially when running code.{' '} {PRODUCT_NAME} has read access to files in the current directory and can run commands and edit files with your permission. {count >= 1 && ( Usage Modes: • REPL: {PRODUCT_COMMAND} (interactive session) • Non-interactive:{' '} {PRODUCT_COMMAND} -p "question" Run {PRODUCT_COMMAND} -h for all command line options )} {count >= 2 && ( Common Tasks: • Ask questions about your codebase{' '} > How does foo.py work? • Edit files{' '} > Update bar.ts to... • Fix errors{' '} > cargo build • Run commands{' '} > /help • Run bash commands{' '} > !ls )} {count >= 3 && ( Built-in Commands: {builtInCommands.map((cmd, i) => ( {`/${cmd.name}`} - {cmd.description} ))} {customCommands.length > 0 && ( <> Custom Commands: {customCommands.map((cmd, i) => ( {`/${cmd.name}`} - {cmd.description} {cmd.aliases && cmd.aliases.length > 0 && ( {' '} (aliases: {cmd.aliases.join(', ')}) )} {/* Show scope indicator for debugging */} {cmd.scope && ( [{cmd.scope}] )} ))} )} {/* Show custom command directory information */} {hasCustomCommands() || customCommands.length > 0 ? ( Custom commands loaded from: • {getCustomCommandDirectories().userClaude} (user: prefix) • {getCustomCommandDirectories().projectClaude} (project: prefix) Use /refresh-commands to reload after changes ) : ( Create custom commands by adding .md files to: • {getCustomCommandDirectories().userClaude} (user: prefix) • {getCustomCommandDirectories().projectClaude} (project: prefix) Use /refresh-commands to reload after creation )} )} {moreHelp} ) }