Inspecteur Sketch
Convertit les designs Sketch en données structurées, ressources image et découpage de page implémentable.
Cas d'utilisation
- Inspecter un document Sketch ouvert ou un calque spécifique
- Extraire les informations de structure, style, texte, couleur, mise en page et ressources
- Générer du HTML/CSS, React, Vue ou toute autre page à partir d'une zone Sketch
Prérequis
- Sketch est en cours d'exécution, le document cible est ouvert
- Le MCP de Sketch est activé : Général -> Autoriser les outils IA à interagir avec les documents ouverts
- Adresse du service MCP :
http://localhost:31126/mcp - Sketch Run Code s'exécute dans l'environnement JavaScriptCore/CocoaScript, pas Node.js standard
Flux obligatoire pour l'implémentation de page
Lors de la génération d'une page à partir de Sketch, le flux suivant doit être strictement respecté. C'est la seule manière d'accomplir la tâche le plus rapidement possible ; l'absence d'une étape est considérée comme un échec.
1. Analyse
Extraire le profil superficiel de la page ou du conteneur cible, confirmer le layerId racine.
2. Détermination des chemins
imageOutputDir: répertoire des images du projet, utiliser de préférence les répertoires existantsimages/,assets/images/,public/images/, etc.workTmpDir: répertoire temporaire, doit contenir au moinsresult.json; en cas de découpage de gros fichier, il contiendra aussimanifest.json, les JSON de section, et les HTML de section.
3. Exportation
Exécuter le script d'exportation dans sketch_run_code.
const sketch = require('sketch');
// Préparation des paramètres
const layerId = '<layerId du calque cible>'; // ID racine du nœud cible obtenu depuis l'étape 1
const outputDir = '<chemin absolu de imageOutputDir>'; // Ex: '/Users/edy/project/images'
const outputJsonPath = '<chemin absolu de workTmpDir/result.json>'; // Ex: '/Users/edy/project/tmp/result.json'
// Exécution du script d'exportation
const exportScript = require('@scripts/export-text-split-assets.js');
const result = exportScript.runExportTextSplitAssets({
layerId: layerId,
outputDir: outputDir,
outputJsonPath: outputJsonPath
});
// Sortie du résultat pour débogage
console.log(JSON.stringify(result, null, 2));
Résultat retourné :
- Succès : retourne des informations statistiques d'exportation
- Échec : retourne un message d'erreur, vérifier si
layerIdest valide et si le chemin a les permissions d'écriture
Remarques :
- Le script s'exécute dans l'environnement Sketch JavaScriptCore, pas Node.js standard
- Les chemins doivent être absolus
- Le répertoire de sortie doit exister, le script ne le crée pas automatiquement
4. Inférence de mise en page et remplacement de result.json
Exécution en shell :
npx tsx @scripts/sketch_layout_ir_inference.ts \
<workTmpDir>/result.json \
<workTmpDir>/result.json
Cette étape transforme la structure brute exportée en un JSON de mise en page unifié directement implémentable, et remplace le fichier result.json d'origine.
Structure du result.json unifié :
kind:flex|grid|absolute|leafdirection:row|column(uniquement pour flex)gap: espacement entre les éléments enfantspadding: marges internes { top, right, bottom, left }justifyContent: alignement flexalignItems: alignement sur l'axe transversalhasAbsoluteChildren:truelorsqu'un conteneurflex/grida des enfantsabsolutedirectscss.position: "relative": émis explicitement lorsqu'un conteneurflex/grida des enfantsabsolutedirectscolumns/rows: nombre de lignes/colonnes de la grille (uniquement pour grid)source: données de complément d'implémentation correspondant au nœud de mise en page actuel, ne conserve que les champs non liés à la mise en page commesourceClass / asset / background / style / decision / backgroundLayers / derivedFrom
5. Après l'inférence de mise en page, orientation obligatoire
Une fois l'inférence de mise en page terminée, il est interdit de décider de la méthode d'implémentation au feeling. Il faut s'appuyer sur le nombre réel de lignes du result.json unifié :
result.jsona moins de ou exactement3000lignes : lire l'intégralité duresult.jsonet réaliser l'implémentation directement, sans découpageresult.jsona plus de3000lignes : suivre obligatoirement le « flux de découpage des gros fichiers », il est interdit de passer l'intégralité du JSON aux étapes suivantes
Exemple de vérification du nombre de lignes :
wc -l <workTmpDir>/result.json
6. Flux pour petits fichiers : implémentation directe
Condition d'application : nombre de lignes de result.json <= 3000
Règles fondamentales (À SUIVRE ABSOLUMENT) :
- Interdiction d'utiliser absolute pour une mise en page normale : seuls les nœuds avec
kind: "absolute"sont autorisés à être positionnés en absolute - Lorsqu'il y a des enfants absolute directs, il faut impérativement faire confiance aux signaux de positionnement de
result.json: si un nœud émethasAbsoluteChildren: trueoucss.position: "relative", l'implémentation doit positionner le conteneur parent en conséquence, sans l'ignorer
Processus de génération :
- Lire l'intégralité du
result.json - Parcourir récursivement l'arbre de mise en page
- Générer le CSS correspondant selon
kind:flex:display: flex; flex-direction: {direction}; gap: {gap}px; ...grid:display: grid; grid-template-columns: repeat({columns}, 1fr); ...absolute:position: relative;pour le parent,position: absolute;pour les enfantsleaf: pas de disposition, seulement le rendu du contenu
- Utiliser directement le
sourcedu nœud courant pour implémenter le texte, l'image, le fond, le style, la décision ; ne pas revenir à l'ancienne structure JSON
7. Flux pour gros fichiers : découpage -> implémentation section par section -> réassemblage
Condition d'application : nombre de lignes de result.json > 3000
7.1 Découpage du JSON
Exécution en shell :
node @scripts/split-result-json.js \
--inputJsonPath=<workTmpDir>/result.json \
--outputDir=<workTmpDir> \
--assetBasePath=images/ \
--splitStrategy=auto
Produit :
<workTmpDir>/manifest.json- Plusieurs JSON de section
- Les
implementationPath,htmlMarker,cssMarkerconvenus manifest.json.root.layoutIR: résumé sémantique de la mise en page principalemanifest.json.sections[].layoutIR: résumé sémantique de la mise en page du nœud de section
7.2 Implémentation d'une section individuelle
Chaque section doit lire uniquement son propre jsonPath et écrire dans son propre implementationPath conformément à manifest.json.
Règles impératives :
- Le flux d'implémentation d'une section individuelle est détaillé dans
@references/single-section-workflow.md - Le fichier de section doit être un fragment : un
<section>+ un<style> - À l'intérieur de la section, écrire uniquement la structure interne et les styles internes, sans définir les marges externes du conteneur de mise en page principal
- Les sélecteurs non racine doivent être isolés par portée via le
className - Si une vérification approfondie est nécessaire, utiliser
@scripts/inspect-single-section.js
7.3 Réassemblage
Une fois toutes les sections implémentées, chaque fragment de section doit être réinséré dans le fichier de mise en page principal. Il est interdit de copier-coller manuellement le contenu des marqueurs.
Le fichier de mise en page principal doit être préparé à l'avance :
htmlMarkerest placé dans la structure de la page à l'endroit où la section doit être inséréecssMarkerdoit être placé à l'intérieur du bloc<style>du fichier de mise en page principal ; il ne doit pas être placé dans d'autres balises, blocs de commentaires ou en dehors de la structure du corps- Si le HTML et le CSS sont dans des fichiers séparés,
cssMarkerdoit être placé dans le fichier CSS pointé parcssLayoutPath
Exécution en shell :
node @scripts/replace-section-placeholder.js \
--layoutPath=/path/layout.html \
--sectionPath=/path/01-section.html \
--htmlMarker="<!-- HTML section 01 -->" \
--cssMarker="/* CSS section 01 */"
Si le HTML et le CSS sont dans des fichiers différents, ajouter l'option --cssLayoutPath.
8. Liste de contrôle avant implémentation
Avant de procéder à l'implémentation, vérifier :
- Lecture complète du
result.json - Vérification du champ
kindde chaque nœud - Vérification des informations de calque de fond
meta.background - Texte, images, relations entre calques déjà vérifiés
- Ressources de marque et groupes visuels complexes identifiés
9. Livraison
Rapporter les éléments objectifs :
- Contour de la mise en page et ID de la zone cible
- Chemin du
result.jsonet nombre réel de lignes - Utilisation du « flux d'implémentation directe pour petits fichiers » ou du « flux de découpage pour gros fichiers »
- Si flux de découpage : chemin du
manifest.json, nombre de sections, chemin du fichier de réassemblage - Statistiques des types de mise en page (nombre de flex/grid/absolute/leaf)
- Liste des ressources exportées
- Chemins des fichiers HTML/CSS générés
Ne pas inclure de conclusions que la machine ne peut pas vérifier, comme « visuellement validé ».
Scripts fixes
Les paramètres et structures de retour des scripts sont détaillés dans @references/script-api.md.
@scripts/export-text-split-assets.js: exporte les images et le JSON. Paramètres obligatoireslayerId,outputDir@scripts/sketch_layout_ir_inference.ts: inférence de mise en page et sortie duresult.jsonunifié@scripts/split-result-json.js: script pour le flux des gros fichiers, génèremanifest.jsonet plusieurs JSON de section@scripts/replace-section-placeholder.js: script pour le flux des gros fichiers, réinsère les implémentations de section dans le fichier de mise en page principal@scripts/inspect-single-section.js: inspection locale approfondie lorsque les informations de section sont insuffisantes
Interdit : générer son propre script d'exportation, copier le code source des scripts, ou réimplémenter la logique de parcours.
Description des types LayoutIR
type LayoutKind = 'leaf' | 'flex' | 'grid' | 'absolute'
interface FlexIR {
kind: 'flex'
direction: 'row' | 'column'
gap: number
padding: { top, right, bottom, left }
justifyContent: 'flex-start' | 'center' | 'flex-end' | 'space-between'
alignItems: 'flex-start' | 'center' | 'flex-end' | 'stretch'
children: LayoutIR[]
}
interface GridIR {
kind: 'grid'
columns: number
rows: number
columnGap: number
rowGap: number
padding: { top, right, bottom, left }
children: LayoutIR[]
}
interface AbsoluteIR {
kind: 'absolute'
children: LayoutIR[] // les enfants doivent être positionnés en absolute
}
interface LeafIR {
kind: 'leaf'
text?: string
css: { width?, height? }
}
Règles d'exportation des ressources
- Les images sont exportées dans
imageOutputDir, les JSON temporaires dansworkTmpDir - Les noms de fichiers image utilisent les 8 premiers caractères du MD5, les images identiques sont réutilisées
asset/exportsne conservent quepath,src,x,y,width,height. Le code généré référencesrc, paspath- Les champs de style vides ou à valeur
0sont supprimés du JSON - Les calques cachés sont filtrés par défaut
- Les nœuds contenant du texte réel doivent être décomposés, ils ne peuvent pas être exportés en une seule image
- Les rectangles d'arrière-plan ordinaires sont reconstruits en code ; les ressources de marque et les groupes visuels complexes sont exportés de préférence avec une haute fidélité
Index des références
@references/export-assets.md: règles d'exportation des ressources@references/script-api.md: paramètres et structures de retour des scripts@references/single-section-workflow.md: flux d'implémentation d'une section individuelle