UNPKG

ollama-code-qwen

Version:

Un assistant IA en ligne de commande utilisant Ollama et le modèle qwen2.5-coder pour aider au développement, avec des capacités MCP améliorées et détection d'intentions en français et anglais

333 lines (289 loc) 7.66 kB
/** * Composant personnalisé de saisie pour contourner les problèmes du textbox de blessed */ import blessed from 'blessed'; export class CustomInput { /** * Crée un composant de saisie personnalisé * @param {Object} options - Options de configuration */ constructor(options = {}) { this.screen = options.screen; this.onSubmit = options.onSubmit || (() => {}); this.onCancel = options.onCancel || (() => {}); // Position et dimensions this.top = options.top || 0; this.left = options.left || 0; this.width = options.width || '100%'; this.height = options.height || 3; // Styles this.style = options.style || { fg: 'white', bg: 'black', border: { fg: 'blue' } }; // État interne this.currentInput = ''; this.cursorPos = 0; this.prefix = options.prefix || '> '; // Historique this.history = []; this.historyIndex = -1; // Créer le composant d'affichage this._createDisplay(); // Mettre en place les gestionnaires d'événements this._setupHandlers(); } /** * Crée le composant d'affichage */ _createDisplay() { this.box = blessed.box({ top: this.top, left: this.left, width: this.width, height: this.height, tags: true, border: { type: 'line' }, style: this.style, content: this.prefix }); // Ajouter à l'écran si fourni if (this.screen) { this.screen.append(this.box); } } /** * Met en place les gestionnaires d'événements */ _setupHandlers() { // Capturer les événements clavier au niveau de l'écran this.screen.on('keypress', (ch, key) => { if (!this.box.focused) return; // Traiter l'événement clavier this._handleKeyPress(ch, key); }); } /** * Traite les événements clavier * @param {string} ch - Caractère saisi * @param {Object} key - Informations sur la touche */ _handleKeyPress(ch, key) { // Si c'est une touche spéciale (pas un caractère) if (!ch || key.ctrl || key.meta || key.shift) { // Touches spéciales switch (key.name) { case 'return': case 'enter': this._submit(); break; case 'escape': this._cancel(); break; case 'backspace': this._backspace(); break; case 'delete': this._delete(); break; case 'left': this._moveCursor(-1); break; case 'right': this._moveCursor(1); break; case 'home': this._moveCursorTo(0); break; case 'end': this._moveCursorTo(this.currentInput.length); break; case 'up': this._historyPrev(); break; case 'down': this._historyNext(); break; } return; } // Ajouter le caractère à la position du curseur this._insertChar(ch); } /** * Insère un caractère à la position actuelle du curseur * @param {string} ch - Caractère à insérer */ _insertChar(ch) { const before = this.currentInput.slice(0, this.cursorPos); const after = this.currentInput.slice(this.cursorPos); this.currentInput = before + ch + after; this.cursorPos++; this._updateDisplay(); } /** * Supprime le caractère à gauche du curseur */ _backspace() { if (this.cursorPos > 0) { const before = this.currentInput.slice(0, this.cursorPos - 1); const after = this.currentInput.slice(this.cursorPos); this.currentInput = before + after; this.cursorPos--; this._updateDisplay(); } } /** * Supprime le caractère à la position du curseur */ _delete() { if (this.cursorPos < this.currentInput.length) { const before = this.currentInput.slice(0, this.cursorPos); const after = this.currentInput.slice(this.cursorPos + 1); this.currentInput = before + after; this._updateDisplay(); } } /** * Déplace le curseur * @param {number} offset - Nombre de positions à déplacer */ _moveCursor(offset) { const newPos = this.cursorPos + offset; if (newPos >= 0 && newPos <= this.currentInput.length) { this.cursorPos = newPos; this._updateDisplay(); } } /** * Déplace le curseur à une position spécifique * @param {number} position - Position où déplacer le curseur */ _moveCursorTo(position) { if (position >= 0 && position <= this.currentInput.length) { this.cursorPos = position; this._updateDisplay(); } } /** * Navigation dans l'historique: précédent */ _historyPrev() { if (this.history.length > 0 && this.historyIndex < this.history.length - 1) { this.historyIndex++; this.currentInput = this.history[this.historyIndex]; this.cursorPos = this.currentInput.length; this._updateDisplay(); } } /** * Navigation dans l'historique: suivant */ _historyNext() { if (this.historyIndex > 0) { this.historyIndex--; this.currentInput = this.history[this.historyIndex]; this.cursorPos = this.currentInput.length; } else if (this.historyIndex === 0) { this.historyIndex = -1; this.currentInput = ''; } this._updateDisplay(); } /** * Met à jour l'affichage */ _updateDisplay() { const before = this.currentInput.slice(0, this.cursorPos); const current = this.currentInput[this.cursorPos] || ' '; const after = this.currentInput.slice(this.cursorPos + 1); // Afficher avec le curseur const displayText = this.prefix + before + '{inverse}' + current + '{/inverse}' + after; this.box.setContent(displayText); this.screen.render(); } /** * Soumet l'entrée */ _submit() { const text = this.currentInput; if (text && this.onSubmit) { this.addToHistory(text); this.onSubmit(text); } // Effacer l'entrée this.currentInput = ''; this.cursorPos = 0; this._updateDisplay(); } /** * Annule l'entrée */ _cancel() { if (this.onCancel) { this.onCancel(); } // Effacer l'entrée this.currentInput = ''; this.cursorPos = 0; this._updateDisplay(); } /** * Ajoute une entrée à l'historique * @param {string} text - Texte à ajouter */ addToHistory(text) { if (text && text.trim()) { // Éviter les duplications if (this.history.length === 0 || this.history[0] !== text) { this.history.unshift(text); } // Limiter la taille de l'historique if (this.history.length > 50) { this.history.pop(); } this.historyIndex = -1; } } /** * Définit le focus sur ce composant */ focus() { this.box.focus(); this._updateDisplay(); } /** * Retourne le composant d'affichage * @returns {Object} - Composant blessed */ getDisplay() { return this.box; } /** * Obtient la valeur actuelle * @returns {string} - Entrée actuelle */ getValue() { return this.currentInput; } /** * Définit la valeur actuelle * @param {string} value - Nouvelle valeur */ setValue(value) { this.currentInput = value || ''; this.cursorPos = this.currentInput.length; this._updateDisplay(); } /** * Efface la valeur actuelle */ clearValue() { this.setValue(''); } }