Point de sauvegarde incluant les fichiers non committés des sessions
précédentes (systemd, docs, agents, GPU manager).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Après la dernière étape, Léa vérifie l'écran et gère les dialogues
restants (jusqu'à 3 vérifications en cascade). Le workflow laisse
l'écran propre à la fin.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Le filtre len<3 bloquait les boutons "OK" (2 chars) et "No" (2 chars).
Seuil abaissé à 2 — filtre les lettres isolées mais laisse passer
les boutons courts courants des dialogues Windows.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
UIPatternLibrary câblée dans l'executor et le stream processor.
Pendant un wait_for_anchor, Léa surveille l'écran toutes les secondes :
1. OCR plein écran (docTR)
2. Pattern matching (dialogues Save, OK, Cancel, cookies...)
3. OCR ciblé pour trouver le bouton par son texte réel
4. Clic sur le match le plus bas (bouton, pas titre)
Fix : seuil ratio supprimé (trigger trouvé = match, quelle que soit
la longueur du texte OCR). Matching strict mot exact ≥3 chars
(évite les faux positifs sur lettres isolées). Fallback recherche
partielle pour les lettres soulignées (E_nregistrer).
Plus aucune coordonnée hardcodée — 100% vision.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
VWB Executor :
- _check_screen_for_patterns() : capture écran + OCR + pattern matching
- _handle_detected_pattern() : clic automatique sur dialogues connus
- Vérifie entre chaque étape en mode intelligent/debug
- Si un dialogue bloque (OK, Save, Cancel), Léa le gère seule
Stream Processor :
- Enrichit les ScreenState avec ui_pattern/ui_pattern_action/ui_pattern_target
- Les patterns détectés sont loggés et stockés dans les résultats
- Permet au GraphBuilder de savoir quels écrans sont des dialogues
Phase 2 du plan "connaissance native de l'environnement".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Le conteneur .fullscreen-content avait height:0 + min-height:0
qui écrasait la hauteur du flex child → image minuscule.
Le wrapper inline-block limitait aussi le dimensionnement.
Fix : overflow:hidden sans height forcée, wrapper en flex 100%.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CSS : le dropdown héritait color:white du header → forcé #212121
sur .workflow-dropdown et .dropdown-item .item-name
Bibliothèque : migration localStorage → backend (capture_library.json)
- GET/POST /api/v3/capture/library (max 50 captures)
- loadLibraryAsync() charge depuis backend, fallback localStorage
- saveLibrary() écrit dans les deux (localStorage + backend)
- capture_library.json gitignored
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Le refresh du layout X11 juste avant xdotool type force le bon keymap.
Sans ça, xdotool envoie des keycodes décalés (: → M, / → !, etc.)
dans les VM spice/QEMU.
Solution trouvée via askubuntu.com/questions/914718.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remet xclip+Ctrl+V comme méthode prioritaire. Les spice tools sont
installés dans la VM → le presse-papier est partagé → pas de problème
de mapping clavier. xdotool envoie des événements synthétiques X11
que spice/QEMU traite différemment des vraies frappes (: → M).
Citrix partage aussi le clipboard nativement → même méthode en prod.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
xdotool type pour les segments alphanumériques (un seul appel, rapide),
xdotool key avec keysym uniquement pour les caractères spéciaux
(:, /, @, etc.) qui cassent en AZERTY dans les VM.
Évite le subprocess par caractère (trop lent, effet visuel désagréable).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
xdotool type envoie des scancodes QWERTY — dans une VM AZERTY,
':' devient 'M', '/' devient '!', etc.
Nouvelle approche : xdotool key avec les noms de keysym X11
(colon, slash, period, etc.) qui sont indépendants du layout.
Chaque caractère est envoyé individuellement — plus lent mais
100% fiable en AZERTY/QWERTY, local ou VM.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
safe_type_text() : xdotool type en priorité au lieu du presse-papier.
Le clipboard xclip ne traverse pas les VM (QEMU) ni Citrix/RDP.
xdotool envoie des frappes X11 réelles que les VM capturent.
Délai 20ms entre caractères pour fiabilité.
Cosmétique : couleur texte forcée sur les items workflow du sidebar
(color: var(--text-primary)) — était blanc sur blanc.
Logs diagnostic ajoutés dans execute_workflow_thread et execute_action.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
MAX_TEMPLATE_DISTANCE dans zoned_template_match était encore à 150px.
Tous les seuils de distance sont maintenant alignés à 500px :
- MAX_DISTANCE_PX (CLIP) : 500
- MAX_GLOBAL_DISTANCE (template global) : 500
- MAX_SEECLICK_DISTANCE : 500
- MAX_TEMPLATE_DISTANCE (template zonée) : 500
Commentaires périmés corrigés (plus de références aux anciennes valeurs).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Le template matching global trouvait l'icône Chrome à 0.99 de confiance
mais la rejetait car elle avait bougé de >150px. Même problème pour
SeeClick (>200px). Aligné tous les seuils de distance à 500px
pour supporter les workflows VWB cross-résolution.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
MAX_DISTANCE_PX 120→500 (ancre peut être loin si résolution différente)
MIN_CLIP_SCORE 0.55→0.50 (tolérance basique suffisante)
MIN_COMBINED_SCORE 0.5→0.45 (accepter les matchs raisonnables)
L'icône Chrome à 81% de confiance était rejetée à cause de la distance.
Les workflows VWB manuels capturent sur un écran et s'exécutent
potentiellement sur un autre — la tolérance de distance doit être large.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Corrige les src={{b64ImgSrc(...)}} → src={b64ImgSrc(...)} causés par
le replace_all sur les template literals. Corrige aussi l'appel
b64ImgSrc dans du code JS pur (pas de {} autour).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CSS fullscreen-content : height:0 + min-height:0 pour forcer flex fill
- Image fullscreen : max-height calc(100vh - 60px) + object-fit contain
- Fonction b64ImgSrc() détecte automatiquement PNG vs JPEG depuis le base64
- Corrige l'affichage des thumbnails compressés JPEG dans la bibliothèque
- Appliqué dans CapturePanel + CaptureLibrary (toutes les occurrences)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Avant : tous les workflows importés s'appelaient « Unnamed Workflow »
→ la liste devenait illisible dès qu'il y en avait plusieurs.
Après : génération d'un nom explicite par _derive_default_name :
1. Premier `template.window.title_pattern` utile dans les nodes
(filtrage de "Unknown" / "unknown_window"), avec extraction de
l'app derrière le séparateur Windows « – » / « - »
(ex: « Sans titre – Bloc-notes » → « Bloc-notes »).
2. Premier `template.window.process_name` non-null
(ex: « explorer.exe »).
3. Fallback : 8 premiers caractères du workflow_id, après
nettoyage des préfixes techniques ("workflow_sess_", ...).
Le nom final inclut toujours la date de l'import :
« Léa Bloc-notes — 2026-04-16 08:41 »
« Léa explorer.exe — 2026-04-16 08:41 »
« Léa 20260404 — 2026-04-16 08:41 » (fallback)
Ne se déclenche que si le nom entrant est vide,
« Unnamed Workflow » ou « Workflow importé » (insensible à la
casse). Le paramètre `name` explicite de la requête reste
prioritaire. L'utilisateur peut renommer via le bouton éditer.
Pas de modification du schema workflow (champ `name` existant).
Tests manuels sur données réelles :
- notepad_enriched.json (tous nodes "Unknown") → fallback id OK
- Bloc-notes, Explorateur et Recherche (2) → « Léa Rechercher »
- workflow construit avec title 'Sans titre – Bloc-notes'
→ « Léa Bloc-notes » OK
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Avant : CaptureLibrary.tsx utilisait sessionStorage (purgé à la
fermeture d'onglet), et CapturePanel.tsx maintenait une liste
concurrente sous une clé différente (captureLibrary vs
captureLibrary_v2) → deux vues désynchronisées qui s'effacent
toutes les deux dès qu'on ferme le navigateur.
Après :
- Nouveau service captureLibraryStorage.ts (load/save/compress)
comme point unique d'accès.
- Stockage en localStorage (persiste entre onglets et sessions).
- Clé unifiée 'captureLibrary_v2'.
- Migration automatique de sessionStorage → localStorage et de
l'ancienne clé 'captureLibrary' → nouvelle, lors du premier load.
- Thumbnails compressés JPEG qualité 80% et redimensionnés à
320×240 max avant stockage pour rester sous le quota navigateur
(5–10 MB selon navigateur).
- Gestion QuotaExceededError dans saveLibrary : élague les items
les plus anciens jusqu'à ce que ça passe (5 tentatives).
- Les deux composants consomment le même helper : fin de la
divergence de format (sessionId/favorite).
Diagnostic (bug reproduit par lecture du code, pas besoin de
navigateur) :
- CaptureLibrary.tsx:28,42,62 → sessionStorage/captureLibrary_v2
- CapturePanel.tsx:53,61 → sessionStorage/captureLibrary
→ Deux sources, toutes deux éphémères.
Vérif : `npx tsc --noEmit` passe (EXITCODE=0).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fichier SQLite vide (toutes tables à 0 lignes), tracé en git mais
jamais peuplé. La vraie source de vérité est `workflows.db`
(DATABASE_URL dans backend/.env → 3 workflows, 115 exécutions,
920 steps).
Risque éliminé : si `.env` n'était pas chargé (ex : systemd mal
configuré), SQLAlchemy retombait sur le fallback
`sqlite:///vwb_v3.db` et l'app créait/utilisait une BDD
complètement vide à côté de la vraie. Foot-gun classique.
Correctif :
- Fallback de app.py aligné sur workflows.db.
- Fichier vwb_v3.db supprimé du repo.
workflows.db reste seule source de vérité.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- B4 : supprime le double logging dans backend/app.py.
app.py est importé 2 fois (une fois comme __main__ via `python app.py`,
une fois comme module `app` via `from app import socketio` dans
api/websocket_handlers.py). Le RotatingFileHandler était donc ajouté
2× au root logger → chaque ligne loguée dupliquée. Fix : garde
idempotente qui vérifie si un handler vers vwb.log existe déjà.
- B6 : supprime les fichiers .pid résiduels (.backend.pid,
.frontend.pid, .frontend_v4.pid) et les ajoute au .gitignore
(avec *.lock, *.orig, *.bak).
- B7 : ajoute launch.sh (wrapper → run_v4.sh par défaut, legacy
→ run.sh), clarifie en tête de run.sh et run_v4.sh la distinction
frontend/ (legacy v3) vs frontend_v4/ (actif), et rectifie le
README.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Token obligatoire (RPA_API_TOKEN) sur /capture et /file-action
- Bind 127.0.0.1 par défaut, 0.0.0.0 exige token (fail-closed)
- /health reste public pour monitoring
- VWB backend injecte le Bearer pour les proxys distants
- hmac.compare_digest pour comparaison temps constant
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Supprime ~8.2 Go de fichiers parasites qui polluent les grep, consomment
des tokens, et ajoutent du bruit au repo :
- _a_trier/ (561 Mo) — scripts legacy, backups, sessions logs, démos
- archives/ (21 Mo) — copie figée code décembre 2024 (déjà dans git history)
- visual_workflow_builder/_a_trier/ (7.6 Go) — backups VWB legacy + anciens frontends
- web_dashboard/app.py.bak_20260304_2225 — fichier .bak oublié
- agent_v1/ (top-level) — scaffold vide jamais alimenté
- core/detection/ui_detector_old.py.bak — .bak traqué par erreur
Retire aussi du tracking git :
- 2 fichiers __pycache__ traqués par erreur dans VWB backend
Met à jour .gitignore pour prévenir la récurrence :
- *.bak, *.bak_*, *.orig, *.old
- _a_trier/, archives/
Tout ce contenu reste récupérable via git history (tag pre-cleanup-phase1-20260410).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 30 crops suffisent pour les éléments UI principaux
- ~6min/screenshot au lieu de 17min (3x plus rapide)
- Bridge cherche aussi dans live_sessions/workflows/
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Workflows appris par Léa visibles dans le VWB ("Appris par Léa")
- Bouton "Importer" pour éditer un workflow appris
- Bouton "Exporter pour Léa" pour rendre un workflow VWB exécutable
- Conversion bidirectionnelle core ↔ VWB via learned_workflow_bridge
- Liste unifiée dans le chat Léa (merged + dédupliquée)
- reload_workflows() sur le streaming server (pas de redémarrage)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Floutage (conformité AI Act) :
- Détection OpenCV des champs de saisie (rectangles clairs avec texte)
- Flou gaussien avant stockage/envoi
- Activé par défaut (RPA_BLUR_SENSITIVE=true)
- <200ms par screenshot, 12 tests
Fix actions fichiers VWB :
- Pas de wait 5s pour les actions fichiers (inutile)
- Routing direct vers agent port 5006
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 5 actions : lister, créer dossier, déplacer, copier, classer par extension
- Exécution sur Windows via agent port 5006
- Sécurité chemins (bloque C:\Windows, /etc, etc.)
- Propriétés panel + preview canvas pour chaque action
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Le proxy injecte x_pct/y_pct depuis le centre du bbox de l'ancre
- Si le visual resolve timeout → clic aux coordonnées bbox (pas à 0,0)
- Lookup replay_states par machine_id (premier replay fonctionne)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- /replay/next cherche dans replay_states par machine_id (pas seulement machine_replay_target)
- execute-windows auto-détecte la machine Windows connectée
- resolve_target utilise ThreadPool par défaut (pas le GPU executor saturé)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Le fix sécurité avait supprimé _machine_replay_target qui est nécessaire
pour router les actions vers la bonne session agent.
Session_id vide dans le frontend = auto-détection serveur.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CaptureServer : serveur HTTP daemon sur l'agent Windows
- Capture fraîche mss en ~94ms à chaque requête
- Plus de lecture de vieux heartbeats sur disque
- Fallback capture locale si agent indisponible
- Firewall Windows port 5006 configuré
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Capture auto : détecte OS navigateur → capture Windows ou Linux
- Timer capture utilise aussi la smart capture
- Heartbeat background permanent (même sans session)
- Tri screenshots par date (plus de vieilles captures)
- Chat Léa : 450x650, polices 11pt, redimensionnable, meilleur contraste
- Bouton Exécuter : "Linux" + "Windows" avec feedback visuel
- Délai 5s avant replay Windows (temps de réduire le navigateur)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Bouton "Windows" dans VWB pour exécuter sur le PC distant
- Template matching OpenCV multi-scale pour localiser les ancres visuelles
- Proxy VWB→streaming server avec chargement ancre (thumb, pas full)
- Fix executor Windows : mss lazy, result reporting, debug prints
- Fix poll replay permanent (sans session active)
- Mapping types VWB→executor (click_anchor→click, type_text→type)
- CORS streaming server, capture Windows dans VWB
- Dédup heartbeats côté client (hash perceptuel)
- Mode cloud VLM configurable via RPA_VLM_MODEL
- Fix resolve_target : pas de ScreenAnalyzer fallback (trop lent)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Bouton ? sur chaque nœud : tooltip avec description + paramètres typés
- Croix rouge visible (fix overflow React Flow)
- Sélection plein écran avec détection auto des éléments UI
- Zones détectées affichées sur l'aperçu de capture
- 32 actions documentées en français avec paramètres typés
- Pruning candidats VLM : max 80 avant classification (3x plus rapide)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Bouton "Parcourir..." ouvre l'explorateur natif du navigateur
- Upload vers /api/v3/upload-excel, sauvegarde dans data/uploads/
- Nom de table auto-suggéré depuis le nom du fichier
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ExcelImporter : import .xlsx → SQLite auto (détection types, batch insert)
- DBIterator : lecture ligne par ligne avec filtre/tri/limite
- VWB actions : "Importer Excel" + "Pour chaque ligne" dans la palette
- DAG executor : pré-exécution import, boucle foreach avec injection
${current_row.colonne} dans les étapes dépendantes
- 36 tests unitaires Excel/DB (tous passent)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>