UNPKG

@fromsvenwithlove/devops-issues-cli

Version:

AI-powered CLI tool and library for Azure DevOps work item management with Claude agents

109 lines (94 loc) 2.56 kB
import keypress from 'keypress'; import { stdinStateManager } from './stdin-state-manager.js'; /** * Global keypress manager to prevent double event registration * This ensures keypress(process.stdin) is only called once per process */ class KeypressManager { constructor() { this.initialized = false; this.handlers = new Map(); this.activeHandlers = 0; } /** * Initialize keypress on stdin if not already done */ init() { if (!this.initialized) { // Check if we're in an interactive terminal if (!process.stdin.isTTY) { return false; } // Save stdin state before modifying stdinStateManager.saveState(); keypress(process.stdin); process.stdin.setRawMode(true); process.stdin.resume(); // Global keypress handler that delegates to registered handlers process.stdin.on('keypress', (ch, key) => { this.handlers.forEach(handler => { try { handler(ch, key); } catch (error) { console.error('Keypress handler error:', error); } }); }); this.initialized = true; } return true; } /** * Add a keypress handler with unique ID * @param {string} id - Unique identifier for this handler * @param {Function} handler - Function to handle keypress events * @returns {boolean} - True if successfully added */ addHandler(id, handler) { if (!this.init()) { return false; } this.handlers.set(id, handler); this.activeHandlers++; return true; } /** * Remove a specific keypress handler * @param {string} id - Handler ID to remove */ removeHandler(id) { if (this.handlers.has(id)) { this.handlers.delete(id); this.activeHandlers--; // If no handlers left, cleanup if (this.activeHandlers <= 0) { this.cleanup(); } } } /** * Force cleanup of all keypress handling */ cleanup() { if (this.initialized) { // Clear our handlers first this.handlers.clear(); this.activeHandlers = 0; // Reset stdin for inquirer compatibility stdinStateManager.resetForInquirer(); this.initialized = false; } } /** * Get current status */ getStatus() { return { initialized: this.initialized, activeHandlers: this.activeHandlers, handlerIds: Array.from(this.handlers.keys()) }; } } // Export singleton instance export const keypressManager = new KeypressManager();