Aktraiser
commited on
Commit
·
fb84cc7
1
Parent(s):
cc5a0ed
docstrings
Browse files- app.py +33 -102
- tools/config.py +18 -2
- tools/figjam.py +114 -9
- tools/figma_design.py +40 -3
- tools/navigation.py +24 -3
- tools/user_account.py +48 -7
app.py
CHANGED
|
@@ -11,51 +11,18 @@ from PIL import Image
|
|
| 11 |
import base64
|
| 12 |
import io
|
| 13 |
|
| 14 |
-
# Import de tous les outils MCP depuis le dossier tools
|
| 15 |
-
from tools import *
|
| 16 |
-
|
| 17 |
# Configuration du logging
|
| 18 |
logging.basicConfig(level=logging.INFO)
|
| 19 |
logger = logging.getLogger(__name__)
|
| 20 |
|
| 21 |
-
#
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
# Navigation
|
| 30 |
-
get_figma_file_info,
|
| 31 |
-
get_figma_comments,
|
| 32 |
-
get_figma_user_info,
|
| 33 |
-
|
| 34 |
-
# Compte utilisateur
|
| 35 |
-
get_figma_user_detailed_info,
|
| 36 |
-
list_figma_user_teams,
|
| 37 |
-
get_figma_team_info,
|
| 38 |
-
get_figma_current_user_permissions,
|
| 39 |
-
get_figma_workspace_usage_stats,
|
| 40 |
-
get_figma_api_limitations_info,
|
| 41 |
-
list_figma_team_projects,
|
| 42 |
-
|
| 43 |
-
# Figma Design
|
| 44 |
-
create_figma_rectangle,
|
| 45 |
-
create_figma_frame,
|
| 46 |
-
create_figma_text,
|
| 47 |
-
|
| 48 |
-
# FigJam
|
| 49 |
-
create_figjam_sticky_note,
|
| 50 |
-
create_figjam_connector_between_elements,
|
| 51 |
-
create_figjam_shape_with_text,
|
| 52 |
-
create_figjam_table,
|
| 53 |
-
create_figjam_code_block,
|
| 54 |
-
create_figjam_background_shape,
|
| 55 |
-
create_figjam_sticker,
|
| 56 |
-
create_figjam_workshop_template,
|
| 57 |
-
create_figjam_organized_zone
|
| 58 |
-
]
|
| 59 |
|
| 60 |
# === CONFIGURATION DE L'APPLICATION GRADIO ===
|
| 61 |
|
|
@@ -86,7 +53,7 @@ def setup_demo():
|
|
| 86 |
|
| 87 |
def test_api_limitations():
|
| 88 |
return get_figma_api_limitations_info()
|
| 89 |
-
|
| 90 |
with gr.Blocks(
|
| 91 |
title="🎨 Figma MCP Server",
|
| 92 |
theme=gr.themes.Soft(),
|
|
@@ -212,7 +179,7 @@ def setup_demo():
|
|
| 212 |
|
| 213 |
gr.Markdown("""
|
| 214 |
---
|
| 215 |
-
### 🛠️ **Outils MCP disponibles :**
|
| 216 |
|
| 217 |
**📋 Configuration :**
|
| 218 |
- `configure_figma_token(token)` - Configure le token d'accès
|
|
@@ -267,50 +234,11 @@ def setup_demo():
|
|
| 267 |
|
| 268 |
---
|
| 269 |
|
| 270 |
-
##
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
-
|
| 274 |
-
-
|
| 275 |
-
- **Informations équipe** : Plan (Starter/Pro/Org), limites d'éditeurs, stockage utilisé
|
| 276 |
-
- **Projets** : Accès aux projets de l'équipe, statistiques d'utilisation
|
| 277 |
-
|
| 278 |
-
### **Via le Plugin API (dans les plugins Figma) :**
|
| 279 |
-
- **Utilisateur actuel** : `figma.currentUser` (nom, email, couleur, session)
|
| 280 |
-
- **Utilisateurs actifs** : `figma.activeUsers` (FigJam uniquement)
|
| 281 |
-
- **Contexte** : Type d'éditeur, mode du plugin, clé du fichier
|
| 282 |
-
- **Permissions** : Accès aux fonctionnalités selon les droits
|
| 283 |
-
|
| 284 |
-
### **Plans d'abonnement détectables :**
|
| 285 |
-
- **Starter** : 3 pages max, fonctionnalités limitées
|
| 286 |
-
- **Professional** : Pages illimitées, fonctionnalités avancées
|
| 287 |
-
- **Organization** : Gestion d'équipe, contrôles admin
|
| 288 |
-
- **Education** : Fonctionnalités spéciales pour l'éducation
|
| 289 |
-
|
| 290 |
-
**💡 Note :** Certaines informations nécessitent des permissions spéciales ou des plugins privés.
|
| 291 |
-
|
| 292 |
-
---
|
| 293 |
-
|
| 294 |
-
## ⚠️ **Limitation importante : Lister les projets**
|
| 295 |
-
|
| 296 |
-
**🚫 L'API Plugin Figma ne peut PAS lister les projets !**
|
| 297 |
-
|
| 298 |
-
Selon la documentation officielle Context7 MCP :
|
| 299 |
-
- L'API Plugin s'exécute uniquement dans le contexte du fichier actuel
|
| 300 |
-
- Aucune fonction `figma.listProjects()` ou équivalent n'existe
|
| 301 |
-
- Pas d'accès aux informations de navigation entre fichiers
|
| 302 |
-
|
| 303 |
-
**✅ Solution : Notre serveur MCP utilise l'API REST**
|
| 304 |
-
- `list_figma_user_teams()` - Via `GET /teams`
|
| 305 |
-
- `list_figma_team_projects(team_id)` - Via `GET /teams/{team_id}/projects`
|
| 306 |
-
- `get_figma_file_info()` - Via `GET /files/{file_id}`
|
| 307 |
-
|
| 308 |
-
**💡 Approche hybride recommandée :**
|
| 309 |
-
1. **API REST** : Navigation, projets, informations utilisateur
|
| 310 |
-
2. **Plugin API** : Création/modification dans le fichier actuel
|
| 311 |
-
3. **Code JavaScript** : Manipulation avancée des objets
|
| 312 |
-
|
| 313 |
-
Utilisez `get_figma_api_limitations_info()` pour plus de détails !
|
| 314 |
""")
|
| 315 |
|
| 316 |
return demo
|
|
@@ -318,18 +246,21 @@ def setup_demo():
|
|
| 318 |
# === LANCEMENT DE L'APPLICATION ===
|
| 319 |
|
| 320 |
if __name__ == "__main__":
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
| 328 |
-
|
| 329 |
-
|
| 330 |
-
|
| 331 |
-
|
| 332 |
-
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
import base64
|
| 12 |
import io
|
| 13 |
|
|
|
|
|
|
|
|
|
|
| 14 |
# Configuration du logging
|
| 15 |
logging.basicConfig(level=logging.INFO)
|
| 16 |
logger = logging.getLogger(__name__)
|
| 17 |
|
| 18 |
+
# Import de tous les outils MCP depuis le dossier tools
|
| 19 |
+
# Gradio détectera automatiquement toutes les fonctions avec docstrings/type hints
|
| 20 |
+
try:
|
| 21 |
+
from tools import *
|
| 22 |
+
logger.info("✅ Tous les outils MCP importés avec succès")
|
| 23 |
+
except Exception as e:
|
| 24 |
+
logger.error(f"❌ Erreur d'import des outils MCP: {e}")
|
| 25 |
+
raise
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
|
| 27 |
# === CONFIGURATION DE L'APPLICATION GRADIO ===
|
| 28 |
|
|
|
|
| 53 |
|
| 54 |
def test_api_limitations():
|
| 55 |
return get_figma_api_limitations_info()
|
| 56 |
+
|
| 57 |
with gr.Blocks(
|
| 58 |
title="🎨 Figma MCP Server",
|
| 59 |
theme=gr.themes.Soft(),
|
|
|
|
| 179 |
|
| 180 |
gr.Markdown("""
|
| 181 |
---
|
| 182 |
+
### 🛠️ **Outils MCP disponibles (détection automatique) :**
|
| 183 |
|
| 184 |
**📋 Configuration :**
|
| 185 |
- `configure_figma_token(token)` - Configure le token d'accès
|
|
|
|
| 234 |
|
| 235 |
---
|
| 236 |
|
| 237 |
+
## 📚 **Documentation Gradio MCP**
|
| 238 |
+
Selon la [documentation officielle](https://www.gradio.app/guides/building-mcp-server-with-gradio) :
|
| 239 |
+
- Gradio détecte **automatiquement** toutes les fonctions avec docstrings et type hints
|
| 240 |
+
- Il suffit de `mcp_server=True` dans `.launch()`
|
| 241 |
+
- Pas besoin d'exposition manuelle des outils
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 242 |
""")
|
| 243 |
|
| 244 |
return demo
|
|
|
|
| 246 |
# === LANCEMENT DE L'APPLICATION ===
|
| 247 |
|
| 248 |
if __name__ == "__main__":
|
| 249 |
+
try:
|
| 250 |
+
demo = setup_demo()
|
| 251 |
+
|
| 252 |
+
logger.info("🚀 Démarrage du serveur MCP Figma...")
|
| 253 |
+
|
| 254 |
+
# Configuration pour Hugging Face Spaces avec MCP
|
| 255 |
+
# Gradio détectera automatiquement toutes les fonctions importées
|
| 256 |
+
demo.launch(
|
| 257 |
+
mcp_server=True, # 🔑 Active le serveur MCP avec détection automatique !
|
| 258 |
+
server_name="0.0.0.0",
|
| 259 |
+
server_port=7860,
|
| 260 |
+
share=False,
|
| 261 |
+
show_error=True
|
| 262 |
+
)
|
| 263 |
+
|
| 264 |
+
except Exception as e:
|
| 265 |
+
logger.error(f"❌ Erreur lors du lancement: {e}")
|
| 266 |
+
raise
|
tools/config.py
CHANGED
|
@@ -51,7 +51,15 @@ def make_figma_request(endpoint: str, method: str = "GET", data: Dict = None) ->
|
|
| 51 |
return {"error": f"Erreur de requête : {str(e)}"}
|
| 52 |
|
| 53 |
def configure_figma_token(token: str) -> str:
|
| 54 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
global figma_config
|
| 56 |
|
| 57 |
if not token or not token.startswith(('figd_', 'figc_')):
|
|
@@ -75,7 +83,15 @@ def configure_figma_token(token: str) -> str:
|
|
| 75 |
return f"❌ Erreur de connexion à l'API Figma : {str(e)}"
|
| 76 |
|
| 77 |
def configure_figma_file_id(file_id: str) -> str:
|
| 78 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
global figma_config
|
| 80 |
|
| 81 |
if not file_id:
|
|
|
|
| 51 |
return {"error": f"Erreur de requête : {str(e)}"}
|
| 52 |
|
| 53 |
def configure_figma_token(token: str) -> str:
|
| 54 |
+
"""
|
| 55 |
+
Configure le token d'accès Figma pour l'API REST.
|
| 56 |
+
|
| 57 |
+
Args:
|
| 58 |
+
token (str): Token d'accès Figma (doit commencer par 'figd_' ou 'figc_')
|
| 59 |
+
|
| 60 |
+
Returns:
|
| 61 |
+
str: Message de confirmation ou d'erreur
|
| 62 |
+
"""
|
| 63 |
global figma_config
|
| 64 |
|
| 65 |
if not token or not token.startswith(('figd_', 'figc_')):
|
|
|
|
| 83 |
return f"❌ Erreur de connexion à l'API Figma : {str(e)}"
|
| 84 |
|
| 85 |
def configure_figma_file_id(file_id: str) -> str:
|
| 86 |
+
"""
|
| 87 |
+
Configure l'ID du fichier Figma à utiliser pour les opérations.
|
| 88 |
+
|
| 89 |
+
Args:
|
| 90 |
+
file_id (str): ID du fichier Figma (extrait de l'URL du fichier)
|
| 91 |
+
|
| 92 |
+
Returns:
|
| 93 |
+
str: Message de confirmation ou d'erreur
|
| 94 |
+
"""
|
| 95 |
global figma_config
|
| 96 |
|
| 97 |
if not file_id:
|
tools/figjam.py
CHANGED
|
@@ -4,7 +4,19 @@
|
|
| 4 |
from .config import figma_config, make_figma_request
|
| 5 |
|
| 6 |
def create_figjam_sticky_note(x: str, y: str, text: str, width: str = "240", height: str = "240") -> str:
|
| 7 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
if not figma_config["file_id"]:
|
| 9 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 10 |
|
|
@@ -33,7 +45,17 @@ def create_figjam_sticky_note(x: str, y: str, text: str, width: str = "240", hei
|
|
| 33 |
return "❌ Les coordonnées et dimensions doivent être des nombres"
|
| 34 |
|
| 35 |
def create_figjam_connector_between_elements(element1_name: str, element2_name: str, style: str = "solid") -> str:
|
| 36 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
if not figma_config["file_id"]:
|
| 38 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 39 |
|
|
@@ -55,7 +77,20 @@ def create_figjam_connector_between_elements(element1_name: str, element2_name:
|
|
| 55 |
return f"✅ Instructions connecteur créées entre {element1_name} et {element2_name}"
|
| 56 |
|
| 57 |
def create_figjam_shape_with_text(x: str, y: str, shape_type: str, text: str, width: str = "208", height: str = "208") -> str:
|
| 58 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
if not figma_config["file_id"]:
|
| 60 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 61 |
|
|
@@ -96,7 +131,18 @@ def create_figjam_shape_with_text(x: str, y: str, shape_type: str, text: str, wi
|
|
| 96 |
return "❌ Les coordonnées et dimensions doivent être des nombres"
|
| 97 |
|
| 98 |
def create_figjam_table(rows: str, columns: str, x: str = "0", y: str = "0") -> str:
|
| 99 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
if not figma_config["file_id"]:
|
| 101 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 102 |
|
|
@@ -125,7 +171,18 @@ def create_figjam_table(rows: str, columns: str, x: str = "0", y: str = "0") ->
|
|
| 125 |
return "❌ Les dimensions et coordonnées doivent être des nombres"
|
| 126 |
|
| 127 |
def create_figjam_code_block(x: str, y: str, code: str, language: str = "javascript") -> str:
|
| 128 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
if not figma_config["file_id"]:
|
| 130 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 131 |
|
|
@@ -156,7 +213,21 @@ def create_figjam_code_block(x: str, y: str, code: str, language: str = "javascr
|
|
| 156 |
return "❌ Les coordonnées doivent être des nombres"
|
| 157 |
|
| 158 |
def create_figjam_background_shape(x: str, y: str, width: str, height: str, color: str = "#F3F4F6", title: str = "", corner_radius: str = "8") -> str:
|
| 159 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
if not figma_config["file_id"]:
|
| 161 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 162 |
|
|
@@ -186,7 +257,18 @@ def create_figjam_background_shape(x: str, y: str, width: str, height: str, colo
|
|
| 186 |
return "❌ Les coordonnées et dimensions doivent être des nombres"
|
| 187 |
|
| 188 |
def create_figjam_sticker(x: str, y: str, sticker_type: str, size: str = "40") -> str:
|
| 189 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 190 |
if not figma_config["file_id"]:
|
| 191 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 192 |
|
|
@@ -239,7 +321,17 @@ def create_figjam_sticker(x: str, y: str, sticker_type: str, size: str = "40") -
|
|
| 239 |
return "❌ Les coordonnées et la taille doivent être des nombres"
|
| 240 |
|
| 241 |
def create_figjam_workshop_template(template_type: str, x: str = "0", y: str = "0") -> str:
|
| 242 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 243 |
if not figma_config["file_id"]:
|
| 244 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 245 |
|
|
@@ -324,7 +416,20 @@ title{i+1}.fontSize = 16""")
|
|
| 324 |
return "❌ Les coordonnées doivent être des nombres"
|
| 325 |
|
| 326 |
def create_figjam_organized_zone(title: str, x: str, y: str, width: str = "400", height: str = "500", max_stickies: str = "12") -> str:
|
| 327 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
if not figma_config["file_id"]:
|
| 329 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 330 |
|
|
|
|
| 4 |
from .config import figma_config, make_figma_request
|
| 5 |
|
| 6 |
def create_figjam_sticky_note(x: str, y: str, text: str, width: str = "240", height: str = "240") -> str:
|
| 7 |
+
"""
|
| 8 |
+
Crée un post-it (sticky note) dans FigJam avec les dimensions officielles.
|
| 9 |
+
|
| 10 |
+
Args:
|
| 11 |
+
x (str): Position X du post-it en pixels
|
| 12 |
+
y (str): Position Y du post-it en pixels
|
| 13 |
+
text (str): Texte à afficher sur le post-it
|
| 14 |
+
width (str): Largeur du post-it en pixels (défaut: 240)
|
| 15 |
+
height (str): Hauteur du post-it en pixels (défaut: 240)
|
| 16 |
+
|
| 17 |
+
Returns:
|
| 18 |
+
str: Message de confirmation ou d'erreur
|
| 19 |
+
"""
|
| 20 |
if not figma_config["file_id"]:
|
| 21 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 22 |
|
|
|
|
| 45 |
return "❌ Les coordonnées et dimensions doivent être des nombres"
|
| 46 |
|
| 47 |
def create_figjam_connector_between_elements(element1_name: str, element2_name: str, style: str = "solid") -> str:
|
| 48 |
+
"""
|
| 49 |
+
Crée un connecteur entre deux éléments FigJam (API officielle).
|
| 50 |
+
|
| 51 |
+
Args:
|
| 52 |
+
element1_name (str): Nom du premier élément à connecter
|
| 53 |
+
element2_name (str): Nom du deuxième élément à connecter
|
| 54 |
+
style (str): Style du connecteur (défaut: solid)
|
| 55 |
+
|
| 56 |
+
Returns:
|
| 57 |
+
str: Message de confirmation ou d'erreur
|
| 58 |
+
"""
|
| 59 |
if not figma_config["file_id"]:
|
| 60 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 61 |
|
|
|
|
| 77 |
return f"✅ Instructions connecteur créées entre {element1_name} et {element2_name}"
|
| 78 |
|
| 79 |
def create_figjam_shape_with_text(x: str, y: str, shape_type: str, text: str, width: str = "208", height: str = "208") -> str:
|
| 80 |
+
"""
|
| 81 |
+
Crée une forme avec texte intégré dans FigJam (API officielle).
|
| 82 |
+
|
| 83 |
+
Args:
|
| 84 |
+
x (str): Position X de la forme en pixels
|
| 85 |
+
y (str): Position Y de la forme en pixels
|
| 86 |
+
shape_type (str): Type de forme (rectangle, circle, triangle, diamond, star, hexagon)
|
| 87 |
+
text (str): Texte à afficher dans la forme
|
| 88 |
+
width (str): Largeur de la forme en pixels (défaut: 208)
|
| 89 |
+
height (str): Hauteur de la forme en pixels (défaut: 208)
|
| 90 |
+
|
| 91 |
+
Returns:
|
| 92 |
+
str: Message de confirmation ou d'erreur
|
| 93 |
+
"""
|
| 94 |
if not figma_config["file_id"]:
|
| 95 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 96 |
|
|
|
|
| 131 |
return "❌ Les coordonnées et dimensions doivent être des nombres"
|
| 132 |
|
| 133 |
def create_figjam_table(rows: str, columns: str, x: str = "0", y: str = "0") -> str:
|
| 134 |
+
"""
|
| 135 |
+
Crée un tableau dans FigJam (API officielle).
|
| 136 |
+
|
| 137 |
+
Args:
|
| 138 |
+
rows (str): Nombre de lignes du tableau
|
| 139 |
+
columns (str): Nombre de colonnes du tableau
|
| 140 |
+
x (str): Position X du tableau en pixels (défaut: 0)
|
| 141 |
+
y (str): Position Y du tableau en pixels (défaut: 0)
|
| 142 |
+
|
| 143 |
+
Returns:
|
| 144 |
+
str: Message de confirmation ou d'erreur
|
| 145 |
+
"""
|
| 146 |
if not figma_config["file_id"]:
|
| 147 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 148 |
|
|
|
|
| 171 |
return "❌ Les dimensions et coordonnées doivent être des nombres"
|
| 172 |
|
| 173 |
def create_figjam_code_block(x: str, y: str, code: str, language: str = "javascript") -> str:
|
| 174 |
+
"""
|
| 175 |
+
Crée un bloc de code dans FigJam (API officielle).
|
| 176 |
+
|
| 177 |
+
Args:
|
| 178 |
+
x (str): Position X du bloc de code en pixels
|
| 179 |
+
y (str): Position Y du bloc de code en pixels
|
| 180 |
+
code (str): Code source à afficher
|
| 181 |
+
language (str): Langage de programmation (défaut: javascript)
|
| 182 |
+
|
| 183 |
+
Returns:
|
| 184 |
+
str: Message de confirmation ou d'erreur
|
| 185 |
+
"""
|
| 186 |
if not figma_config["file_id"]:
|
| 187 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 188 |
|
|
|
|
| 213 |
return "❌ Les coordonnées doivent être des nombres"
|
| 214 |
|
| 215 |
def create_figjam_background_shape(x: str, y: str, width: str, height: str, color: str = "#F3F4F6", title: str = "", corner_radius: str = "8") -> str:
|
| 216 |
+
"""
|
| 217 |
+
Crée une forme de fond rectangulaire pour organiser le contenu FigJam.
|
| 218 |
+
|
| 219 |
+
Args:
|
| 220 |
+
x (str): Position X de la forme en pixels
|
| 221 |
+
y (str): Position Y de la forme en pixels
|
| 222 |
+
width (str): Largeur de la forme en pixels
|
| 223 |
+
height (str): Hauteur de la forme en pixels
|
| 224 |
+
color (str): Couleur de fond en format hex (défaut: #F3F4F6)
|
| 225 |
+
title (str): Titre de la zone (optionnel)
|
| 226 |
+
corner_radius (str): Rayon des coins en pixels (défaut: 8)
|
| 227 |
+
|
| 228 |
+
Returns:
|
| 229 |
+
str: Message de confirmation ou d'erreur
|
| 230 |
+
"""
|
| 231 |
if not figma_config["file_id"]:
|
| 232 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 233 |
|
|
|
|
| 257 |
return "❌ Les coordonnées et dimensions doivent être des nombres"
|
| 258 |
|
| 259 |
def create_figjam_sticker(x: str, y: str, sticker_type: str, size: str = "40") -> str:
|
| 260 |
+
"""
|
| 261 |
+
Crée un sticker/emoji dans FigJam pour les réactions et annotations.
|
| 262 |
+
|
| 263 |
+
Args:
|
| 264 |
+
x (str): Position X du sticker en pixels
|
| 265 |
+
y (str): Position Y du sticker en pixels
|
| 266 |
+
sticker_type (str): Type de sticker (thumbs_up, heart, fire, etc.)
|
| 267 |
+
size (str): Taille du sticker en pixels (défaut: 40)
|
| 268 |
+
|
| 269 |
+
Returns:
|
| 270 |
+
str: Message de confirmation ou d'erreur
|
| 271 |
+
"""
|
| 272 |
if not figma_config["file_id"]:
|
| 273 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 274 |
|
|
|
|
| 321 |
return "❌ Les coordonnées et la taille doivent être des nombres"
|
| 322 |
|
| 323 |
def create_figjam_workshop_template(template_type: str, x: str = "0", y: str = "0") -> str:
|
| 324 |
+
"""
|
| 325 |
+
Crée des templates d'atelier FigJam prêts à utiliser.
|
| 326 |
+
|
| 327 |
+
Args:
|
| 328 |
+
template_type (str): Type de template (retrospective, brainstorm, user_journey)
|
| 329 |
+
x (str): Position X du template en pixels (défaut: 0)
|
| 330 |
+
y (str): Position Y du template en pixels (défaut: 0)
|
| 331 |
+
|
| 332 |
+
Returns:
|
| 333 |
+
str: Message de confirmation ou d'erreur
|
| 334 |
+
"""
|
| 335 |
if not figma_config["file_id"]:
|
| 336 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 337 |
|
|
|
|
| 416 |
return "❌ Les coordonnées doivent être des nombres"
|
| 417 |
|
| 418 |
def create_figjam_organized_zone(title: str, x: str, y: str, width: str = "400", height: str = "500", max_stickies: str = "12") -> str:
|
| 419 |
+
"""
|
| 420 |
+
Crée une zone organisée avec grille pour post-its dans FigJam.
|
| 421 |
+
|
| 422 |
+
Args:
|
| 423 |
+
title (str): Titre de la zone organisée
|
| 424 |
+
x (str): Position X de la zone en pixels
|
| 425 |
+
y (str): Position Y de la zone en pixels
|
| 426 |
+
width (str): Largeur de la zone en pixels (défaut: 400)
|
| 427 |
+
height (str): Hauteur de la zone en pixels (défaut: 500)
|
| 428 |
+
max_stickies (str): Nombre maximum de post-its dans la grille (défaut: 12)
|
| 429 |
+
|
| 430 |
+
Returns:
|
| 431 |
+
str: Message de confirmation ou d'erreur
|
| 432 |
+
"""
|
| 433 |
if not figma_config["file_id"]:
|
| 434 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 435 |
|
tools/figma_design.py
CHANGED
|
@@ -4,7 +4,20 @@
|
|
| 4 |
from .config import figma_config, make_figma_request
|
| 5 |
|
| 6 |
def create_figma_rectangle(x: str, y: str, width: str, height: str, name: str = "Rectangle", color: str = "#FF0000") -> str:
|
| 7 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
if not figma_config["file_id"]:
|
| 9 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 10 |
|
|
@@ -34,7 +47,19 @@ def create_figma_rectangle(x: str, y: str, width: str, height: str, name: str =
|
|
| 34 |
return "❌ Les coordonnées et dimensions doivent être des nombres"
|
| 35 |
|
| 36 |
def create_figma_frame(x: str, y: str, width: str, height: str, name: str = "Frame") -> str:
|
| 37 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
if not figma_config["file_id"]:
|
| 39 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 40 |
|
|
@@ -63,7 +88,19 @@ def create_figma_frame(x: str, y: str, width: str, height: str, name: str = "Fra
|
|
| 63 |
return "❌ Les coordonnées et dimensions doivent être des nombres"
|
| 64 |
|
| 65 |
def create_figma_text(x: str, y: str, text: str, name: str = "Text", font_size: str = "16") -> str:
|
| 66 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
if not figma_config["file_id"]:
|
| 68 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 69 |
|
|
|
|
| 4 |
from .config import figma_config, make_figma_request
|
| 5 |
|
| 6 |
def create_figma_rectangle(x: str, y: str, width: str, height: str, name: str = "Rectangle", color: str = "#FF0000") -> str:
|
| 7 |
+
"""
|
| 8 |
+
Crée un rectangle dans Figma via commentaire pour notification.
|
| 9 |
+
|
| 10 |
+
Args:
|
| 11 |
+
x (str): Position X du rectangle en pixels
|
| 12 |
+
y (str): Position Y du rectangle en pixels
|
| 13 |
+
width (str): Largeur du rectangle en pixels
|
| 14 |
+
height (str): Hauteur du rectangle en pixels
|
| 15 |
+
name (str): Nom du rectangle (défaut: Rectangle)
|
| 16 |
+
color (str): Couleur du rectangle en format hex (défaut: #FF0000)
|
| 17 |
+
|
| 18 |
+
Returns:
|
| 19 |
+
str: Message de confirmation ou d'erreur
|
| 20 |
+
"""
|
| 21 |
if not figma_config["file_id"]:
|
| 22 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 23 |
|
|
|
|
| 47 |
return "❌ Les coordonnées et dimensions doivent être des nombres"
|
| 48 |
|
| 49 |
def create_figma_frame(x: str, y: str, width: str, height: str, name: str = "Frame") -> str:
|
| 50 |
+
"""
|
| 51 |
+
Crée un frame dans Figma via commentaire pour notification.
|
| 52 |
+
|
| 53 |
+
Args:
|
| 54 |
+
x (str): Position X du frame en pixels
|
| 55 |
+
y (str): Position Y du frame en pixels
|
| 56 |
+
width (str): Largeur du frame en pixels
|
| 57 |
+
height (str): Hauteur du frame en pixels
|
| 58 |
+
name (str): Nom du frame (défaut: Frame)
|
| 59 |
+
|
| 60 |
+
Returns:
|
| 61 |
+
str: Message de confirmation ou d'erreur
|
| 62 |
+
"""
|
| 63 |
if not figma_config["file_id"]:
|
| 64 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 65 |
|
|
|
|
| 88 |
return "❌ Les coordonnées et dimensions doivent être des nombres"
|
| 89 |
|
| 90 |
def create_figma_text(x: str, y: str, text: str, name: str = "Text", font_size: str = "16") -> str:
|
| 91 |
+
"""
|
| 92 |
+
Crée un élément texte dans Figma via commentaire pour notification.
|
| 93 |
+
|
| 94 |
+
Args:
|
| 95 |
+
x (str): Position X du texte en pixels
|
| 96 |
+
y (str): Position Y du texte en pixels
|
| 97 |
+
text (str): Contenu du texte à afficher
|
| 98 |
+
name (str): Nom de l'élément texte (défaut: Text)
|
| 99 |
+
font_size (str): Taille de la police en pixels (défaut: 16)
|
| 100 |
+
|
| 101 |
+
Returns:
|
| 102 |
+
str: Message de confirmation ou d'erreur
|
| 103 |
+
"""
|
| 104 |
if not figma_config["file_id"]:
|
| 105 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 106 |
|
tools/navigation.py
CHANGED
|
@@ -5,7 +5,15 @@ import json
|
|
| 5 |
from .config import figma_config, make_figma_request
|
| 6 |
|
| 7 |
def get_figma_file_info(file_id: str = "") -> str:
|
| 8 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
file_id = file_id or figma_config["file_id"]
|
| 10 |
|
| 11 |
if not file_id:
|
|
@@ -26,7 +34,15 @@ def get_figma_file_info(file_id: str = "") -> str:
|
|
| 26 |
return f"📄 **Fichier Figma :**\n{json.dumps(file_info, indent=2, ensure_ascii=False)}"
|
| 27 |
|
| 28 |
def get_figma_comments(file_id: str = "") -> str:
|
| 29 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
file_id = file_id or figma_config["file_id"]
|
| 31 |
|
| 32 |
if not file_id:
|
|
@@ -52,7 +68,12 @@ def get_figma_comments(file_id: str = "") -> str:
|
|
| 52 |
return f"📝 **Commentaires récents :**\n" + "\n\n".join(comment_list)
|
| 53 |
|
| 54 |
def get_figma_user_info() -> str:
|
| 55 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
result = make_figma_request("me")
|
| 57 |
|
| 58 |
if "error" in result:
|
|
|
|
| 5 |
from .config import figma_config, make_figma_request
|
| 6 |
|
| 7 |
def get_figma_file_info(file_id: str = "") -> str:
|
| 8 |
+
"""
|
| 9 |
+
Récupère les informations détaillées d'un fichier Figma.
|
| 10 |
+
|
| 11 |
+
Args:
|
| 12 |
+
file_id (str): ID du fichier Figma (optionnel, utilise la configuration par défaut si vide)
|
| 13 |
+
|
| 14 |
+
Returns:
|
| 15 |
+
str: Informations du fichier au format JSON ou message d'erreur
|
| 16 |
+
"""
|
| 17 |
file_id = file_id or figma_config["file_id"]
|
| 18 |
|
| 19 |
if not file_id:
|
|
|
|
| 34 |
return f"📄 **Fichier Figma :**\n{json.dumps(file_info, indent=2, ensure_ascii=False)}"
|
| 35 |
|
| 36 |
def get_figma_comments(file_id: str = "") -> str:
|
| 37 |
+
"""
|
| 38 |
+
Récupère tous les commentaires d'un fichier Figma.
|
| 39 |
+
|
| 40 |
+
Args:
|
| 41 |
+
file_id (str): ID du fichier Figma (optionnel, utilise la configuration par défaut si vide)
|
| 42 |
+
|
| 43 |
+
Returns:
|
| 44 |
+
str: Liste des commentaires ou message d'erreur
|
| 45 |
+
"""
|
| 46 |
file_id = file_id or figma_config["file_id"]
|
| 47 |
|
| 48 |
if not file_id:
|
|
|
|
| 68 |
return f"📝 **Commentaires récents :**\n" + "\n\n".join(comment_list)
|
| 69 |
|
| 70 |
def get_figma_user_info() -> str:
|
| 71 |
+
"""
|
| 72 |
+
Récupère les informations de l'utilisateur connecté.
|
| 73 |
+
|
| 74 |
+
Returns:
|
| 75 |
+
str: Informations utilisateur au format JSON ou message d'erreur
|
| 76 |
+
"""
|
| 77 |
result = make_figma_request("me")
|
| 78 |
|
| 79 |
if "error" in result:
|
tools/user_account.py
CHANGED
|
@@ -5,7 +5,12 @@ import json
|
|
| 5 |
from .config import figma_config, make_figma_request
|
| 6 |
|
| 7 |
def get_figma_user_detailed_info() -> str:
|
| 8 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
result = make_figma_request("me")
|
| 10 |
|
| 11 |
if "error" in result:
|
|
@@ -25,7 +30,15 @@ def get_figma_user_detailed_info() -> str:
|
|
| 25 |
return f"👤 **Informations détaillées utilisateur :**\n{json.dumps(user_info, indent=2, ensure_ascii=False)}"
|
| 26 |
|
| 27 |
def get_figma_team_info(team_id: str = "") -> str:
|
| 28 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
team_id = team_id or figma_config.get("team_id", "")
|
| 30 |
|
| 31 |
if not team_id:
|
|
@@ -52,7 +65,12 @@ def get_figma_team_info(team_id: str = "") -> str:
|
|
| 52 |
return f"🏢 **Informations équipe :**\n{json.dumps(team_info, indent=2, ensure_ascii=False)}"
|
| 53 |
|
| 54 |
def list_figma_user_teams() -> str:
|
| 55 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
result = make_figma_request("teams")
|
| 57 |
|
| 58 |
if "error" in result:
|
|
@@ -74,7 +92,12 @@ def list_figma_user_teams() -> str:
|
|
| 74 |
return f"🏢 **Équipes de l'utilisateur :**\n\n" + "\n\n".join(team_list)
|
| 75 |
|
| 76 |
def get_figma_current_user_permissions() -> str:
|
| 77 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
if not figma_config["file_id"]:
|
| 79 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 80 |
|
|
@@ -132,7 +155,12 @@ if (figma.fileKey) {{
|
|
| 132 |
return f"✅ Code généré pour récupérer les permissions et infos utilisateur"
|
| 133 |
|
| 134 |
def get_figma_workspace_usage_stats() -> str:
|
| 135 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
if not figma_config.get("team_id"):
|
| 137 |
return "❌ ID de l'équipe requis. Utilisez list_figma_user_teams() pour trouver votre équipe puis configurez figma_config['team_id']"
|
| 138 |
|
|
@@ -161,7 +189,12 @@ def get_figma_workspace_usage_stats() -> str:
|
|
| 161 |
return f"📊 **Statistiques d'utilisation :**\n{json.dumps(stats, indent=2, ensure_ascii=False)}"
|
| 162 |
|
| 163 |
def get_figma_api_limitations_info() -> str:
|
| 164 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 165 |
|
| 166 |
limitations_info = {
|
| 167 |
"api_plugin_limitations": {
|
|
@@ -212,7 +245,15 @@ def get_figma_api_limitations_info() -> str:
|
|
| 212 |
return f"📚 **Limitations et capacités des APIs Figma :**\n{json.dumps(limitations_info, indent=2, ensure_ascii=False)}"
|
| 213 |
|
| 214 |
def list_figma_team_projects(team_id: str = "") -> str:
|
| 215 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 216 |
team_id = team_id or figma_config["team_id"]
|
| 217 |
|
| 218 |
if not team_id:
|
|
|
|
| 5 |
from .config import figma_config, make_figma_request
|
| 6 |
|
| 7 |
def get_figma_user_detailed_info() -> str:
|
| 8 |
+
"""
|
| 9 |
+
Récupère les informations détaillées de l'utilisateur connecté avec plus de données.
|
| 10 |
+
|
| 11 |
+
Returns:
|
| 12 |
+
str: Informations détaillées utilisateur au format JSON ou message d'erreur
|
| 13 |
+
"""
|
| 14 |
result = make_figma_request("me")
|
| 15 |
|
| 16 |
if "error" in result:
|
|
|
|
| 30 |
return f"👤 **Informations détaillées utilisateur :**\n{json.dumps(user_info, indent=2, ensure_ascii=False)}"
|
| 31 |
|
| 32 |
def get_figma_team_info(team_id: str = "") -> str:
|
| 33 |
+
"""
|
| 34 |
+
Récupère les informations détaillées d'une équipe Figma incluant le plan d'abonnement.
|
| 35 |
+
|
| 36 |
+
Args:
|
| 37 |
+
team_id (str): ID de l'équipe Figma (optionnel, utilise la configuration par défaut si vide)
|
| 38 |
+
|
| 39 |
+
Returns:
|
| 40 |
+
str: Informations équipe au format JSON ou message d'erreur
|
| 41 |
+
"""
|
| 42 |
team_id = team_id or figma_config.get("team_id", "")
|
| 43 |
|
| 44 |
if not team_id:
|
|
|
|
| 65 |
return f"🏢 **Informations équipe :**\n{json.dumps(team_info, indent=2, ensure_ascii=False)}"
|
| 66 |
|
| 67 |
def list_figma_user_teams() -> str:
|
| 68 |
+
"""
|
| 69 |
+
Liste toutes les équipes auxquelles l'utilisateur appartient.
|
| 70 |
+
|
| 71 |
+
Returns:
|
| 72 |
+
str: Liste des équipes avec rôles et plans ou message d'erreur
|
| 73 |
+
"""
|
| 74 |
result = make_figma_request("teams")
|
| 75 |
|
| 76 |
if "error" in result:
|
|
|
|
| 92 |
return f"🏢 **Équipes de l'utilisateur :**\n\n" + "\n\n".join(team_list)
|
| 93 |
|
| 94 |
def get_figma_current_user_permissions() -> str:
|
| 95 |
+
"""
|
| 96 |
+
Récupère les permissions et capacités de l'utilisateur actuel dans un fichier.
|
| 97 |
+
|
| 98 |
+
Returns:
|
| 99 |
+
str: Code JavaScript pour récupérer les permissions ou message d'erreur
|
| 100 |
+
"""
|
| 101 |
if not figma_config["file_id"]:
|
| 102 |
return "❌ ID du fichier requis. Utilisez configure_figma_file_id() d'abord."
|
| 103 |
|
|
|
|
| 155 |
return f"✅ Code généré pour récupérer les permissions et infos utilisateur"
|
| 156 |
|
| 157 |
def get_figma_workspace_usage_stats() -> str:
|
| 158 |
+
"""
|
| 159 |
+
Récupère les statistiques d'utilisation de l'espace de travail.
|
| 160 |
+
|
| 161 |
+
Returns:
|
| 162 |
+
str: Statistiques d'utilisation au format JSON ou message d'erreur
|
| 163 |
+
"""
|
| 164 |
if not figma_config.get("team_id"):
|
| 165 |
return "❌ ID de l'équipe requis. Utilisez list_figma_user_teams() pour trouver votre équipe puis configurez figma_config['team_id']"
|
| 166 |
|
|
|
|
| 189 |
return f"📊 **Statistiques d'utilisation :**\n{json.dumps(stats, indent=2, ensure_ascii=False)}"
|
| 190 |
|
| 191 |
def get_figma_api_limitations_info() -> str:
|
| 192 |
+
"""
|
| 193 |
+
Explique les limitations de l'API Plugin Figma vs l'API REST pour la gestion des projets.
|
| 194 |
+
|
| 195 |
+
Returns:
|
| 196 |
+
str: Documentation détaillée des limitations et capacités des APIs Figma
|
| 197 |
+
"""
|
| 198 |
|
| 199 |
limitations_info = {
|
| 200 |
"api_plugin_limitations": {
|
|
|
|
| 245 |
return f"📚 **Limitations et capacités des APIs Figma :**\n{json.dumps(limitations_info, indent=2, ensure_ascii=False)}"
|
| 246 |
|
| 247 |
def list_figma_team_projects(team_id: str = "") -> str:
|
| 248 |
+
"""
|
| 249 |
+
Liste les projets d'une équipe Figma.
|
| 250 |
+
|
| 251 |
+
Args:
|
| 252 |
+
team_id (str): ID de l'équipe Figma (optionnel, utilise la configuration par défaut si vide)
|
| 253 |
+
|
| 254 |
+
Returns:
|
| 255 |
+
str: Liste des projets de l'équipe ou message d'erreur
|
| 256 |
+
"""
|
| 257 |
team_id = team_id or figma_config["team_id"]
|
| 258 |
|
| 259 |
if not team_id:
|