# Framework SVG per il Team — Analisi Definitiva

**Destinatario:** Sviluppatore responsabile del repo `team-ai-tools`
**Scopo:** Implementazione di un framework completo per la generazione, modifica e composizione di asset SVG tramite agenti AI
**Stato:** Analisi architetturale di riferimento per roadmap multi-fase

> Nota di posizionamento: questo documento descrive la visione architetturale e il perimetro funzionale del framework SVG.
> La pianificazione operativa, le fasi di adozione e i criteri di promozione verso il ramo principale
> sono definiti nel documento di roadmap dedicato: `docs/svg/svg-framework-roadmap.md`.

---

## 1. Contesto e obiettivi

Il framework nasce dall'esigenza di dotare il team di strumenti agentici per produrre asset SVG di qualità professionale senza dipendere da abbonamenti a servizi creativi esterni. I casi d'uso primari sono:

- Generazione di loghi e icone
- Generazione di etichette
- Illustrazioni per form di login di applicazioni professionali
- Illustrazioni in stile minimale per siti vetrina
- Conversione di immagini raster (JPG/PNG) in SVG vettoriali
- Modifica di SVG esistenti

Il framework si articola in tre componenti strettamente integrati: **struttura del repo**, **skill per gli agenti**, **asset locali e tool CLI**.

---

## 2. Limiti fondamentali da tenere presenti

Prima di definire l'architettura è necessario chiarire cosa un LLM sa fare con SVG e cosa non sa fare, per evitare aspettative errate.

| Capacità | Livello | Note |
|---|---|---|
| Geometrie astratte e pattern | Alto | Eccellente |
| Icone flat e loghi semplici | Alto | Risultati affidabili |
| Etichette e layout testo | Alto | Ottimo controllo |
| Grafici e diagrammi | Alto | Nessun problema |
| Illustrazioni flat/minimal | Discreto | Funziona per stili semplici |
| Scene con figure umane | Basso | Proporzioni e prospettiva degradano |
| Illustrazioni complesse | Non affidabile | Richiederebbe modelli specializzati |
| Conversione raster → SVG | Non nativo | Richiede tool CLI esterni |

Per le **scene con figure umane** (es. due persone sedute a un tavolo) la soluzione adottata è l'opzione delle **librerie di illustrazioni open source**: l'agente non disegna da zero ma seleziona, combina e personalizza asset preesistenti. Questo è il cuore del workflow di illustrazione descritto in questo documento.

---

## 3. Struttura del repo

### 3.1 Struttura completa

```
team-ai-tools/
├── mcp/
│   ├── svg-mcp/                    # SVG-MCP (validazione, render, diff)
│   └── ...altri MCP del team...
│
├── skills/
│   └── svg/                        # Tutte le skill SVG (dettaglio §4)
│
└── assets/
    ├── README.md                   # Licenze, istruzioni aggiornamento
    ├── index.json                  # Indice generato da build-asset-index.py
    ├── icons/
    │   ├── lucide/                 # git submodule
    │   ├── heroicons/              # git submodule
    │   ├── tabler/                 # git submodule
    │   └── phosphor/              # git submodule
    └── illustrations/
        └── open-peeps/             # git submodule
```

### 3.2 Strategia git submodule vs copia diretta

Le librerie di asset vengono gestite come **git submodule**, non come file copiati direttamente nel repo. Motivazioni:

- Il repo principale non si gonfia con migliaia di file SVG
- `git submodule update --remote` aggiorna tutto in un comando
- Ogni submodule punta a un commit preciso: l'ambiente è riproducibile
- Le skill referenziano path relativi stabili (es. `../../skills/svg/assets/libraries/lucide/`)

### 3.3 Comandi di setup

```bash
# Prima installazione (nuovo sviluppatore)
git clone <url-repo> --recurse-submodules

# Aggiornamento periodico
git pull
git submodule update --remote --merge

# Rigenerazione indice dopo aggiornamento submodule
python scripts/build-asset-index.py
```

Aggiungere un `setup.sh` nella root del repo che esegua i tre comandi in sequenza, per semplificare l'onboarding dei nuovi sviluppatori.

### 3.4 Submodule da configurare

Nota di governance (pilot Fase 4, 2026-04-22):
- per l'avvio operativo si limita il perimetro a 2 librerie: `lucide` + `open-peeps`;
- le altre librerie restano candidate future e non fanno parte del pilot iniziale.

Aggiornamento pilot Fase 4 (2026-04-24):
- `lucide` resta gestita come submodule Git;
- `open-peeps` viene vendorizzata direttamente da `https://www.openpeeps.com/`, perche' non e' disponibile un repository Git ufficiale adatto al pin come submodule.

```bash
# Illustrazioni
# open-peeps: vendor diretto da https://www.openpeeps.com/

# Icone
git submodule add https://github.com/lucide-icons/lucide skills/svg/assets/libraries/lucide
git submodule add https://github.com/tailwindlabs/heroicons assets/icons/heroicons
git submodule add https://github.com/tabler/tabler-icons assets/icons/tabler
git submodule add https://github.com/phosphor-icons/homepage assets/icons/phosphor
```

### 3.5 Librerie escluse dal repo (accesso via API o web)

| Risorsa | Motivo esclusione | Accesso |
|---|---|---|
| unDraw | API gratuita, pack enorme e in continuo aggiornamento | API REST |
| Haikei | Tool web generativo, niente pack statico | Web |
| Blobs.app | Generatore parametrico | Web |
| SVGBackgrounds | Pattern web | Web |

unDraw ha un'API pubblica e gratuita che la skill `search.md` interroga direttamente:
```
GET https://undraw.co/api/illustrations?q={query}
```
Restituisce JSON con URL SVG scaricabili on-demand.

---

## 4. Struttura delle skill SVG

```
skills/svg/
├── SKILL.md                        # Router principale — entry point obbligatorio
│
├── illustration/                   # Workflow composizione da librerie open source
│   ├── SKILL.md                    # Orchestratore del workflow
│   ├── search.md                   # Ricerca su unDraw API + indice locale
│   ├── select.md                   # Scoring coerenza stilistica
│   ├── compose.md                  # Layout a zone, normalizzazione viewBox/palette
│   ├── refine.md                   # Sostituzione colori, SVGO, validazione
│   └── libraries/
│       ├── undraw.md               # Endpoint API, parametri, formato risposta
│       └── openpeeps.md            # Struttura pack locale, naming convention
│
├── from-raster.md                  # Conversione JPG/PNG → SVG
├── optimize.md                     # Pipeline SVGO con preset per use case
├── validate.md                     # Accessibilità, compatibilità browser
├── animate.md                      # Aggiunta animazioni CSS/SMIL
├── to-component.md                 # Output React/Vue con props parametriche
├── sprite.md                       # Aggregazione in sprite sheet
├── color-palette.md                # Estrazione e applicazione palette
├── brand-kit.md                    # Applicazione brand identity su set di SVG
│
└── export/
    ├── to-pdf.md                   # SVG → PDF print-ready
    ├── to-png-batch.md             # Export multiplo 1x/2x/3x
    └── pdf-to-svg.md               # Estrazione pagine PDF come SVG
```

---

## 5. Descrizione delle skill

### 5.1 SKILL.md — Router principale

Entry point che l'agente legge per primo. Analizza la richiesta e indirizza alla skill appropriata. Deve contenere:

- Mappa use case → skill (es. "genera illustrazione per sito" → `illustration/SKILL.md`)
- Istruzioni per leggere il sotto-file corretto prima di procedere
- Riferimento ai path degli asset locali (`../../assets/`)
- Istruzione esplicita: verificare sempre la disponibilità dei tool CLI necessari prima di eseguirli (pattern check → ask → install → retry, dettagliato in §5.3)

### 5.2 illustration/SKILL.md — Orchestratore workflow illustrazioni

Gestisce il workflow completo in quattro fasi sequenziali:

**Fase 1 — Search** (legge `search.md`)
Analizza il brief (tema, stile, mood, palette). Genera query per ciascuna sorgente. Interroga in parallelo unDraw API e l'indice locale Open Peeps. Raccoglie N candidati per sorgente.

**Fase 2 — Select** (legge `select.md`)
Filtra i candidati per coerenza stilistica tra loro e rispetto al brief. Assegna uno score di compatibilità. Seleziona il set finale di asset. **Nota critica:** non mescolare asset di librerie con stili incompatibili (es. unDraw e Open Peeps hanno linguaggi visivi distanti). La skill deve preferire la coerenza alla varietà.

**Fase 3 — Compose** (legge `compose.md`)
Scarica gli SVG selezionati. Normalizza viewBox, unità di misura e palette. Applica layout a zone predefinite:
- `background`: sfondi, pattern, elementi decorativi
- `midground`: oggetti principali (tavoli, arredi, elementi di scena)
- `foreground`: figure, elementi in primo piano

Ogni zona ha regole di posizionamento, scala relativa e z-index. La composizione è parametrica, non libera, per garantire risultati prevedibili.

**Fase 4 — Refine** (legge `refine.md`)
Sostituisce i colori con la palette del brand/brief. Rimuove metadati non necessari. Esegue ottimizzazione SVGO. Valida con SVG-MCP (render PNG + visual check). Se la validazione rileva problemi, itera sul passo di composizione.

### 5.3 from-raster.md — Conversione raster → SVG

Questa skill gestisce la conversione di JPG/PNG in SVG tramite tool CLI. Include il **pattern di installazione condizionale**:

```
1. CHECK: verifica se il tool necessario è installato
   - vtracer: `which vtracer`
   - potrace: `which potrace`
   - inkscape: `which inkscape`

2. Se non installato:
   ASK: "Il tool [nome] non è installato. Procedo con l'installazione?"

3. Se confermato:
   INSTALL: esegui il comando di installazione appropriato

4. RETRY: esegui la conversione
```

Selezione del tool in base all'input:

| Scenario | Tool consigliato | Comando |
|---|---|---|
| Immagine a colori, risultato scalabile | vtracer | `vtracer --input img.png --output out.svg` |
| Logo B/W o silhouette | potrace | Richiede pre-conversione a BMP |
| Conversione generica o da PDF | inkscape CLI | `inkscape --export-type=svg input.png` |

Installazione dei tool:

```bash
# vtracer (Rust)
cargo install vtracer

# potrace
sudo apt install potrace      # Linux
brew install potrace           # macOS

# inkscape (headless)
sudo apt install inkscape      # Linux
brew install --cask inkscape   # macOS
```

**Nota:** Il risultato della vettorizzazione è un SVG tecnico con path complessi, non editabile a mano. È adatto per illustrazioni decorative e asset web, non per loghi che devono essere modificati successivamente.

### 5.4 optimize.md — Ottimizzazione SVGO

Pipeline SVGO con preset differenziati per use case. Installazione: `npm install -g svgo`. Applica il pattern di installazione condizionale (§5.3).

Preset consigliati:

```json
// Logo: conservativo, preserva struttura
{ "plugins": ["preset-default", { "name": "removeViewBox", "active": false }] }

// Web: aggressivo, minimizza peso
{ "plugins": ["preset-default", "removeDimensions"] }

// Print: preserva tutto, solo pulizia metadati
{ "plugins": [{ "name": "removeMetadata" }, { "name": "removeComments" }] }
```

### 5.5 validate.md — Validazione e accessibilità

Checklist che l'agente esegue su ogni SVG prima della consegna:

- Presenza di `<title>` e `<desc>` per accessibilità screen reader
- Attributo `role="img"` sull'elemento root
- `aria-labelledby` che punta al `<title>`
- viewBox definito (non solo width/height)
- Nessun riferimento a font esterni non disponibili offline
- Nessun `<script>` inline (sicurezza)
- Compatibilità: niente funzionalità CSS non supportate da Safari/Firefox

Validazione strutturale via SVG-MCP:
```
svg-mcp validate input.svg
svg-mcp render input.svg output.png --width 800
```

### 5.6 color-palette.md

Due modalità:

**Estrazione:** dato un SVG o un'immagine, identifica i colori dominanti e produce una palette HEX ordinata per frequenza d'uso.

**Applicazione:** data una palette HEX di input, sostituisce i colori in uno o più SVG mantenendo le relazioni tonali (es. colore primario → colore brand, colore secondario → variante chiara del brand).

Questa skill è prerequisito di `brand-kit.md` e viene richiamata dal refiner del workflow illustrazioni.

### 5.7 brand-kit.md

Data una palette colori e opzionalmente un font, applica brand identity coerente su un set di SVG (logo, icone, illustrazioni). Internamente orchestra `color-palette.md` per la sostituzione e `optimize.md` per la pulizia finale. Output: cartella con tutti gli asset aggiornati e un file `brand-manifest.json` con la palette applicata.

### 5.8 to-component.md

Converte un SVG in un componente React o Vue con props parametriche. Parametri tipici esposti: `color`, `size`, `className` (React) / `class` (Vue). La skill gestisce anche la sanitizzazione degli attributi SVG non validi in JSX (es. `class` → `className`, `stroke-width` → `strokeWidth`).

### 5.9 animate.md

Aggiunge animazioni a SVG statici esistenti. Due approcci:

- **CSS animations:** per animazioni semplici e loop (fade, rotate, pulse). Più compatibile.
- **SMIL:** per animazioni lungo path o morphing. Supporto browser da verificare caso per caso.

La skill include snippet template per le animazioni più comuni (spinner, pulse, draw-on, float).

### 5.10 sprite.md

Aggrega N SVG in un unico file sprite usando il pattern `<symbol>`/`<use>`. Output compatibile con l'approccio `<svg><use href="#icon-name"/></svg>` nei template HTML. Genera anche un file di riferimento con tutti gli ID disponibili.

### 5.11 export/

Tre skill di conversione output:

| Skill | Tool | Installazione |
|---|---|---|
| `to-pdf.md` | cairosvg | `pip install cairosvg` |
| `to-png-batch.md` | inkscape CLI o cairosvg | vedi sopra |
| `pdf-to-svg.md` | pdf2svg o inkscape | `apt install pdf2svg` |

Tutte applicano il pattern di installazione condizionale (§5.3).

---

## 6. MCP Server: SVG-MCP

### 6.1 Ruolo nel framework

SVG-MCP non genera SVG: fornisce all'agente un **loop di feedback visivo** durante la generazione e modifica. È il componente che trasforma il workflow da "genera e spera" a "genera, verifica, correggi".

Funzionalità:
- Validazione SVG con messaggi di errore e numeri di riga
- Rendering SVG → PNG per verifica visiva
- Visual diff tra due versioni SVG
- Ottimizzazione e linting
- Mapping coordinate SVG → pixel

### 6.2 Installazione

```bash
pipx install git+https://github.com/adamryczkowski/SVG-MCP.git
```

### 6.3 Configurazione in claude_desktop_config.json

```json
{
  "mcpServers": {
    "svg-mcp": {
      "command": "svg-mcp",
      "args": ["serve"]
    }
  }
}
```

### 6.4 Posizione nel repo

```
team-ai-tools/
└── mcp/
    └── svg-mcp/
        └── README.md    # Istruzioni installazione e configurazione per il team
```

---

## 7. Tool CLI necessari

Riepilogo completo di tutti i tool CLI utilizzati dalle skill, con comando di installazione e note:

| Tool | Funzione | Installazione Linux | Installazione macOS | Note |
|---|---|---|---|---|
| `svgo` | Ottimizzazione SVG | `npm install -g svgo` | idem | Richiede Node.js |
| `vtracer` | Raster → SVG (colori) | `cargo install vtracer` | idem | Richiede Rust/cargo |
| `potrace` | Raster B/W → SVG | `apt install potrace` | `brew install potrace` | Pre-conversione a BMP necessaria |
| `inkscape` | Tutto (headless) | `apt install inkscape` | `brew install --cask inkscape` | Tool universale, pesante |
| `cairosvg` | SVG → PDF/PNG | `pip install cairosvg` | idem | Richiede Python |
| `pdf2svg` | PDF → SVG | `apt install pdf2svg` | `brew install pdf2svg` | Alternativa a inkscape |

**Principio generale:** nessuna skill deve fallire silenziosamente se un tool non è installato. Ogni skill che dipende da un tool CLI deve sempre applicare il pattern check → ask → install → retry descritto in §5.3.

---

## 8. Indice degli asset locali

### 8.1 Motivazione

Le skill di ricerca devono poter cercare tra migliaia di SVG locali in modo rapido e strutturato. Fare glob sul filesystem a ogni chiamata è lento e poco affidabile. La soluzione è un file `skills/svg/assets/index.json` generato da uno script e aggiornato dopo ogni `git submodule update`.

### 8.2 Struttura dell'indice

```json
{
  "generated_at": "2026-04-14T10:00:00Z",
  "assets": [
    {
      "id": "open-peeps-sitting-001",
      "library": "open-peeps",
      "category": "poses",
      "tags": ["sitting", "person", "casual", "relaxed"],
      "path": "skills/svg/assets/libraries/open-peeps/sitting/001.svg",
      "style": "flat",
      "has_background": false,
      "color_scheme": "monochrome"
    },
    {
      "id": "lucide-coffee",
      "library": "lucide",
      "category": "icons",
      "tags": ["coffee", "drink", "cup", "beverage"],
      "path": "skills/svg/assets/libraries/lucide/coffee.svg",
      "style": "outline",
      "stroke_width": 2
    }
  ]
}
```

### 8.3 Script di generazione

Creare/aggiornare `scripts/build-svg-asset-index.js`. Lo script deve:
1. Scansionare ricorsivamente `skills/svg/assets/libraries/`
2. Per ogni SVG: estrarre nome file, path relativo, libreria di appartenenza
3. Derivare tag da nome file e struttura delle cartelle
4. Scrivere `skills/svg/assets/index.json`

Lo script va eseguito manualmente dopo ogni `git submodule update --remote` e può essere aggiunto come hook post-merge se si vuole automatizzare.

---

## 9. Librerie e risorse: riepilogo decisionale

### Nel repo (submodule)

| Libreria | Tipo | Licenza | Dimensione approssimativa |
|---|---|---|---|
| Open Peeps | Illustrazioni figure umane modulari | CC0 | ~50MB |
| Lucide | Icone (1000+) | MIT | ~5MB |
| Heroicons | Icone Tailwind-native, 2 stili | MIT | ~3MB |
| Tabler Icons | Icone (5000+) | MIT | ~20MB |
| Phosphor Icons | Icone con 6 pesi | MIT | ~30MB |

### Accesso remoto (API o web)

| Risorsa | Accesso | Uso nel framework |
|---|---|---|
| unDraw | API REST gratuita | Ricerca e download on-demand nella skill `search.md` |
| Haikei | Web | Uso manuale per sfondi complessi |
| Blobs.app | Web | Uso manuale per forme organiche |

### Non incluse

Humaaans e Storyset sono escluse: Humaaans non ha un pack scaricabile strutturato, Storyset richiede autenticazione e non è pensata per automazione.

---

## 10. Flusso di lavoro tipico per use case

### Logo semplice
```
SKILL.md → (routing) → agente scrive SVG direttamente
                      → optimize.md (SVGO preset logo)
                      → validate.md
```

### Illustrazione per sito vetrina con figure
```
SKILL.md → illustration/SKILL.md
         → search.md (unDraw API + indice Open Peeps)
         → select.md (scoring coerenza)
         → compose.md (layout a zone)
         → refine.md (palette + SVGO + SVG-MCP visual check)
```

### Conversione logo da PNG
```
SKILL.md → from-raster.md
         → check tool disponibili
         → (se non presenti: ask → install)
         → vtracer/potrace/inkscape
         → optimize.md
         → validate.md
```

### Set icone per applicazione
```
SKILL.md → ricerca in skills/svg/assets/index.json (libreria Lucide/Tabler)
         → color-palette.md (applicazione palette brand)
         → sprite.md (aggregazione in sprite sheet)
         → optimize.md
```

### Asset coordinati per brand
```
SKILL.md → brand-kit.md
         → color-palette.md (estrazione o input manuale)
         → applicazione su tutti gli SVG del set
         → optimize.md su ogni file
         → export/to-png-batch.md (1x/2x/3x)
```

---

## 11. Considerazioni finali per l'implementatore

**Ordine di implementazione consigliato:**

1. Struttura cartelle repo + submodule (§3)
2. Script `build-svg-asset-index.js` + generazione `skills/svg/assets/index.json` (§8)
3. `skills/svg/SKILL.md` — router principale
4. `skills/svg/from-raster.md` — include il pattern install condizionale, usato come riferimento per tutte le altre
5. `skills/svg/optimize.md` e `skills/svg/validate.md` — prerequisiti trasversali
6. `skills/svg/illustration/` — workflow completo in ordine: SKILL.md, search.md, select.md, compose.md, refine.md, poi i file in `libraries/`
7. Skill rimanenti in ordine di priorità per il team

**Pattern install condizionale:** implementarlo una volta in `from-raster.md` come riferimento esplicito. Nelle altre skill citarlo con "applica il pattern di installazione condizionale definito in `from-raster.md`" per evitare duplicazioni.

**SVG-MCP:** va installato su ogni macchina sviluppatore, non è un componente del repo. Il `mcp/svg-mcp/README.md` deve contenere istruzioni chiare e il blocco JSON di configurazione da incollare nel `claude_desktop_config.json`.

**Aggiornamento librerie:** stabilire una cadenza (es. mensile) per eseguire `git submodule update --remote` e rigenerare l'indice. Un aggiornamento non coordinato può introdurre breaking changes nei path referenziati dalle skill — valutare se usare commit fissi o `--remote` a seconda della tolleranza al rischio del team.
