#!/usr/bin/env python3 """ deploy_windows.py — Script de packaging du client Windows pour Agent V1. ⚠️ OBSOLÈTE (avril 2026) Le build officiel du package Windows passe par ``deploy/build_package.sh`` (à la racine du repo) qui lit directement ``agent_v0/agent_v1/`` et évite les clones intermédiaires. Ce script est conservé pour référence mais son manifeste ``FILE_MANIFEST`` est incomplet : il n'inclut pas ``system_dialog_guard.py``, ``persistent_buffer.py``, ``recovery.py``, ``uia_helper.py``, ``grounding.py``, ``policy.py``, ``vision/blur_sensitive.py``, ``vision/system_info.py``, ``ui/chat_window.py``, ``ui/capture_server.py``, ``ui/shared_state.py``. Ne PAS l'utiliser pour un packaging réel. Copie uniquement les fichiers nécessaires au fonctionnement de l'agent sur le PC cible (Windows), sans le serveur ni les dépendances lourdes. Usage : python deploy_windows.py # Crée le dossier deploy/windows_client/ python deploy_windows.py --zip # Idem + archive .zip """ from __future__ import annotations import argparse import os import shutil import sys from datetime import datetime from pathlib import Path # Répertoire racine de agent_v0 (là où vit ce script) AGENT_V0_DIR = Path(__file__).resolve().parent # Répertoire de sortie DEPLOY_DIR = AGENT_V0_DIR / "deploy" / "windows_client" # ───────────────────────────────────────────────────────── # Manifeste des fichiers à déployer # Chaque entrée : (source relative à agent_v0, destination relative à windows_client) # ───────────────────────────────────────────────────────── FILE_MANIFEST: list[tuple[str, str]] = [ # === agent_v1 — package principal === ("agent_v1/__init__.py", "agent_v1/__init__.py"), ("agent_v1/config.py", "agent_v1/config.py"), ("agent_v1/main.py", "agent_v1/main.py"), ("agent_v1/window_info.py", "agent_v1/window_info.py"), ("agent_v1/window_info_crossplatform.py", "agent_v1/window_info_crossplatform.py"), # agent_v1/core ("agent_v1/core/__init__.py", "agent_v1/core/__init__.py"), ("agent_v1/core/captor.py", "agent_v1/core/captor.py"), ("agent_v1/core/executor.py", "agent_v1/core/executor.py"), # agent_v1/network ("agent_v1/network/__init__.py", "agent_v1/network/__init__.py"), ("agent_v1/network/streamer.py", "agent_v1/network/streamer.py"), # agent_v1/session ("agent_v1/session/__init__.py", "agent_v1/session/__init__.py"), ("agent_v1/session/storage.py", "agent_v1/session/storage.py"), # agent_v1/ui — smart_tray (PAS tray.py, c'est l'ancien PyQt5) ("agent_v1/ui/__init__.py", "agent_v1/ui/__init__.py"), ("agent_v1/ui/notifications.py", "agent_v1/ui/notifications.py"), ("agent_v1/ui/smart_tray.py", "agent_v1/ui/smart_tray.py"), # agent_v1/vision ("agent_v1/vision/__init__.py", "agent_v1/vision/__init__.py"), ("agent_v1/vision/capturer.py", "agent_v1/vision/capturer.py"), # agent_v1/monitoring ("agent_v1/monitoring/__init__.py", "agent_v1/monitoring/__init__.py"), # === lea_ui — communication chat/workflow (utilisée par smart_tray) === ("lea_ui/__init__.py", "lea_ui/__init__.py"), ("lea_ui/server_client.py", "lea_ui/server_client.py"), # === Racine agent_v0 — fichiers nécessaires à l'exécution === ("__init__.py", "__init__.py"), ("config.py", "config.py"), ("agent_config.json", "agent_config.json"), ("run_agent_v1.py", "run_agent_v1.py"), ("setup_v1.bat", "setup.bat"), ("agent_v1/requirements.txt", "requirements.txt"), ] # Contenu du fichier LISEZMOI.txt LISEZMOI_CONTENT = """\ === Agent V1 — RPA Vision — Client Windows === Installation : 1. Double-cliquer sur setup.bat 2. Configurer le serveur : éditer agent_config.json ou définir la variable RPA_SERVER_HOST=192.168.1.x 3. Lancer : python run_agent_v1.py L'agent apparaît dans la zone de notification (systray). Clic droit pour accéder au menu : démarrer une session, lancer un replay, voir les workflows appris, etc. Léa communique par des notifications toast sur votre écran. Prérequis : - Python 3.10 ou plus récent - Connexion réseau vers le serveur Linux """ def nettoyer_deploy_dir() -> None: """Supprime le répertoire de déploiement s'il existe déjà.""" if DEPLOY_DIR.exists(): print(f" Nettoyage de {DEPLOY_DIR} ...") shutil.rmtree(DEPLOY_DIR) def copier_fichiers() -> tuple[list[str], list[str]]: """ Copie tous les fichiers du manifeste vers le répertoire de déploiement. Retourne : (fichiers_copies, fichiers_manquants) — deux listes de chemins relatifs """ copies: list[str] = [] manquants: list[str] = [] for src_rel, dst_rel in FILE_MANIFEST: src = AGENT_V0_DIR / src_rel dst = DEPLOY_DIR / dst_rel if not src.exists(): print(f" [ATTENTION] Fichier manquant, ignoré : {src_rel}") manquants.append(src_rel) continue # Créer les répertoires parents si nécessaire dst.parent.mkdir(parents=True, exist_ok=True) shutil.copy2(src, dst) copies.append(dst_rel) return copies, manquants def creer_lisezmoi() -> None: """Crée le fichier LISEZMOI.txt dans le répertoire de déploiement.""" lisezmoi_path = DEPLOY_DIR / "LISEZMOI.txt" lisezmoi_path.write_text(LISEZMOI_CONTENT, encoding="utf-8") print(f" LISEZMOI.txt créé") def creer_archive_zip() -> Path: """ Crée une archive .zip du répertoire de déploiement. Retourne le chemin de l'archive créée. """ horodatage = datetime.now().strftime("%Y%m%d_%H%M%S") nom_archive = f"windows_client_{horodatage}" chemin_archive = DEPLOY_DIR.parent / nom_archive # shutil.make_archive ajoute automatiquement l'extension .zip archive_path = shutil.make_archive( str(chemin_archive), "zip", root_dir=str(DEPLOY_DIR.parent), base_dir="windows_client", ) return Path(archive_path) def afficher_resume(copies: list[str], manquants: list[str], archive: Path | None) -> None: """Affiche un résumé des opérations effectuées.""" print() print("=" * 55) print(" Résumé du déploiement — Agent V1 Client Windows") print("=" * 55) print(f" Destination : {DEPLOY_DIR}") print(f" Fichiers copiés : {len(copies)}") if manquants: print(f" Fichiers manquants : {len(manquants)}") for f in manquants: print(f" - {f}") if archive: taille_mo = archive.stat().st_size / (1024 * 1024) print(f" Archive : {archive.name} ({taille_mo:.1f} Mo)") print() # Afficher l'arborescence simplifiée print(" Arborescence :") for f in sorted(copies): print(f" {f}") print() print(" Terminé.") print("=" * 55) def main() -> None: parser = argparse.ArgumentParser( description="Prépare le package de déploiement Windows pour Agent V1" ) parser.add_argument( "--zip", action="store_true", help="Créer aussi une archive .zip du package", ) args = parser.parse_args() print() print("=== Déploiement Agent V1 — Client Windows ===") print() # Étape 1 : Nettoyage nettoyer_deploy_dir() # Étape 2 : Création du répertoire de déploiement DEPLOY_DIR.mkdir(parents=True, exist_ok=True) print(f" Répertoire créé : {DEPLOY_DIR}") # Étape 3 : Copie des fichiers print(" Copie des fichiers...") copies, manquants = copier_fichiers() # Étape 4 : Création du LISEZMOI.txt creer_lisezmoi() # Étape 5 : Archive .zip (optionnel) archive = None if args.zip: print(" Création de l'archive .zip...") archive = creer_archive_zip() print(f" Archive créée : {archive}") # Résumé afficher_resume(copies, manquants, archive) if __name__ == "__main__": main()