UNPKG

@every-env/cli

Version:

Multi-agent orchestrator for AI-powered development workflows

135 lines 5.01 kB
import { useInput } from 'ink'; import { useCallback } from 'react'; const phaseActions = { 1: { d: 'delegate', a: 'assess', e: 'edit', x: 'delete' }, 2: { a: 'assess', l: 'logs', s: 'stop' }, 3: { c: 'codify', d: 'delegate', v: 'view' }, 4: { v: 'view', e: 'edit', p: 'publish' } }; export function useKeyboardNavigation({ state, dispatch, onCreateTask, onExecuteAction }) { const getCurrentPhaseTasks = useCallback(() => { const phaseMap = { 1: 'plan', 2: 'delegate', 3: 'assess', 4: 'codify' }; const phaseKey = phaseMap[state.currentPhase]; return state.tasks[phaseKey]; }, [state.currentPhase, state.tasks]); const navigateUp = useCallback(() => { const currentTasks = getCurrentPhaseTasks(); if (currentTasks.length === 0) return; if (state.selectedIndex === null || state.selectedIndex === 0) { dispatch({ type: 'SET_SELECTED_INDEX', index: currentTasks.length - 1 }); } else { dispatch({ type: 'SET_SELECTED_INDEX', index: state.selectedIndex - 1 }); } }, [getCurrentPhaseTasks, state.selectedIndex, dispatch]); const navigateDown = useCallback(() => { const currentTasks = getCurrentPhaseTasks(); if (currentTasks.length === 0) return; if (state.selectedIndex === null || state.selectedIndex === currentTasks.length - 1) { dispatch({ type: 'SET_SELECTED_INDEX', index: 0 }); } else { dispatch({ type: 'SET_SELECTED_INDEX', index: state.selectedIndex + 1 }); } }, [getCurrentPhaseTasks, state.selectedIndex, dispatch]); const jumpToPhase = useCallback((phase) => { dispatch({ type: 'SET_PHASE', phase }); }, [dispatch]); const executeDefaultAction = useCallback(() => { const actions = Object.values(phaseActions[state.currentPhase]); if (actions.length > 0 && state.selectedIndex !== null) { onExecuteAction(actions[0]); } }, [state.currentPhase, state.selectedIndex, onExecuteAction]); const startTyping = useCallback((key) => { dispatch({ type: 'SET_INPUT_MODE', mode: 'typing' }); dispatch({ type: 'SET_INPUT_VALUE', value: key }); }, [dispatch]); const cancelTyping = useCallback(() => { dispatch({ type: 'SET_INPUT_MODE', mode: 'idle' }); dispatch({ type: 'SET_INPUT_VALUE', value: '' }); }, [dispatch]); const handleEscape = useCallback(() => { if (state.showHelp) { dispatch({ type: 'SET_SHOW_HELP', show: false }); } else if (state.showLogs) { dispatch({ type: 'SET_SHOW_LOGS', taskId: null }); } else if (state.inputMode === 'typing') { cancelTyping(); } }, [state.showHelp, state.showLogs, state.inputMode, dispatch, cancelTyping]); useInput((input, key) => { // Handle typing mode differently if (state.inputMode === 'typing') { if (key.return) { onCreateTask(state.inputValue); cancelTyping(); } else if (key.escape) { cancelTyping(); } else if (key.backspace || key.delete) { dispatch({ type: 'SET_INPUT_VALUE', value: state.inputValue.slice(0, -1) }); } else if (input) { dispatch({ type: 'SET_INPUT_VALUE', value: state.inputValue + input }); } return; } // Navigation keys if (key.upArrow || input === 'k') { navigateUp(); } else if (key.downArrow || input === 'j') { navigateDown(); } else if (key.escape) { handleEscape(); } else if (key.return) { executeDefaultAction(); } // Phase jumping else if (input === '1') { jumpToPhase(1); } else if (input === '2') { jumpToPhase(2); } else if (input === '3') { jumpToPhase(3); } else if (input === '4') { jumpToPhase(4); } // Help else if (input === '?') { dispatch({ type: 'SET_SHOW_HELP', show: true }); } // Context-aware actions else if (input && state.selectedIndex !== null) { const actions = phaseActions[state.currentPhase]; if (actions[input]) { onExecuteAction(actions[input]); } else if (/^[a-zA-Z0-9\s]$/.test(input)) { // Start typing if it's an alphanumeric key startTyping(input); } } // Start typing for any alphanumeric key when no selection else if (input && /^[a-zA-Z0-9\s]$/.test(input)) { startTyping(input); } }); } //# sourceMappingURL=useKeyboardNavigation.js.map