mirror of
https://github.com/R0m1k3/EveFlow.git
synced 2026-10-12 01:39:13 +02:00
Serveur MCP local - Endpoint /mcp (JSON-RPC 2.0, Streamable HTTP, réponses JSON) sur le serveur webhook : initialize, tools/list, tools/call, ping. Même secret que le webhook. 14 outils : capture_screen (image MCP), lock_session, open_app, open_url, media_key, clipboard_get/set, find_files, speak_text, notify_user, set_hud_state, get_app_status, get_conversation_history, show_message. Les outils UI transitent par IPC vers le renderer. - Les mêmes actions système sont proposées au modèle en chat completions. Notifications - Heures calmes (plage horaire, franchissement de minuit), mots prioritaires, échecs de crons toujours lus, résumé vocal des messages entrants (n premières phrases), thème nuit automatique, compteur de non-lus. Conversation - Mode mission : bouton dans la barre de commande, second modèle Hermes (hermes.missionModel) pour les tâches longues. - Barge-in : la parole de l'utilisateur coupe la voix ; seuil d'énergie et ratio relevés pendant la synthèse pour ignorer l'écho. Widget compact - Bandeau glanceable : état, dernière phrase, non-lus, indicateurs heures calmes et mission. Tests : 28 tests unitaires (heures calmes, priorité, résumé), e2e Electron sous Xvfb : MCP initialize/tools/list/tools/call (presse-papiers, capture en image, état et message via le renderer), bandeau compact, aucune erreur. Claude-Session: https://claude.ai/code/session_017Wn5VX9HNbJ7N54hR24u9Y Co-authored-by: Claude <noreply@anthropic.com>
38 lines
1.7 KiB
TypeScript
38 lines
1.7 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
||
import { isPriority, isQuietTime, summarize } from '../src/lib/quietHours';
|
||
|
||
const at = (h: number, m = 0) => new Date(2026, 0, 1, h, m);
|
||
|
||
describe('isQuietTime', () => {
|
||
it('handles ranges crossing midnight', () => {
|
||
expect(isQuietTime('22:30', '07:30', at(23))).toBe(true);
|
||
expect(isQuietTime('22:30', '07:30', at(3, 15))).toBe(true);
|
||
expect(isQuietTime('22:30', '07:30', at(7, 30))).toBe(false);
|
||
expect(isQuietTime('22:30', '07:30', at(12))).toBe(false);
|
||
});
|
||
it('handles same-day ranges and invalid input', () => {
|
||
expect(isQuietTime('13:00', '14:00', at(13, 30))).toBe(true);
|
||
expect(isQuietTime('13:00', '14:00', at(14))).toBe(false);
|
||
expect(isQuietTime('bad', '14:00', at(13))).toBe(false);
|
||
expect(isQuietTime('10:00', '10:00', at(10))).toBe(false);
|
||
});
|
||
});
|
||
|
||
describe('isPriority', () => {
|
||
it('matches keywords in text or job name', () => {
|
||
expect(isPriority('Serveur en panne depuis 5 min', 'urgent, panne')).toBe(true);
|
||
expect(isPriority('Rapport quotidien', 'urgent', 'Alerte disque')).toBe(false);
|
||
expect(isPriority('Rapport quotidien', 'alerte', 'Alerte disque')).toBe(true);
|
||
expect(isPriority('x', '')).toBe(false);
|
||
});
|
||
});
|
||
|
||
describe('summarize', () => {
|
||
it('keeps the first sentences and strips markdown', () => {
|
||
const text = '## Rapport\n\nTrois annonces **majeures** aujourd’hui. Le marché monte de 2 %. Détails ci-dessous :\n\n```\ncode\n```\n- point 1';
|
||
expect(summarize(text, 2)).toBe('Rapport Trois annonces majeures aujourd’hui. Le marché monte de 2 %.');
|
||
expect(summarize('Une seule phrase', 2)).toBe('Une seule phrase');
|
||
expect(summarize('', 2)).toBe('');
|
||
});
|
||
});
|