Salta al contenuto principale

18 - Copilot Extensions e Marketplace

Estendi Copilot con Extensions e Skillsets dal Marketplace. Integrazione MCP, third-party agents (Claude, Codex) e come creare la tua estensione personalizzata.

Cosa ne pensi di questo articolo?

18 - Copilot Extensions e Marketplace
GitHub CopilotFoto:Christina MorilloPexels

In Breve

Estendi Copilot con Extensions e Skillsets dal Marketplace. Integrazione MCP, third-party agents (Claude, Codex) e come creare la tua estensione personalizzata.

Copilot Extensions e Marketplace

GitHub Copilot e' progettato per essere estensibile. Attraverso le Copilot Extensions, e' possibile ampliare le capacità' dell'assistente AI con integrazioni di terze parti, strumenti personalizzati e agenti specializzati. Le extensions permettono di collegare Copilot a database, servizi cloud, piattaforme di testing, strumenti di monitoring e molto altro, trasformandolo in un hub centralizzato per l'intero workflow di sviluppo.

In questo articolo esploreremo l'ecosistema delle extensions, le tipologie disponibili, come integrarle nel proprio flusso di lavoro e come costruire estensioni personalizzate per le esigenze specifiche del proprio team.

Panoramica della Serie Completa

#ArticoloFocus
1Foundation e MindsetSetup e mentalita'
2Ideazione e RequisitiDa idea a MVP
3Architettura Backend/FrontendAPI e database
4Struttura del CodiceOrganizzazione e naming
5Prompt EngineeringPrompt e Agenti MCP
6Testing e qualità'Unit, integration, E2E
7DocumentazioneREADME, API docs, ADR
8Deploy e DevOpsDocker, CI/CD
9EvoluzioneScalabilità' e manutenzione
10Coding AgentAgente autonomo GitHub
11Code ReviewReview automatizzata
12Copilot EditsEditing multi-file
13GitHub SparkMicro-app senza codice
14Copilot SpacesContesto condiviso
15Modelli AIMulti-model e selezione
16PersonalizzazioneIstruzioni e configurazione
17Enterprise e BusinessPiani, analytics, policy
18Sei qui → Extensions e MarketplaceEstensioni e integrazioni
19Sicurezza e Uso ResponsabileSecurity e compliance

Panoramica delle Copilot Extensions

Le Copilot Extensions sono applicazioni che estendono le funzionalità' di GitHub Copilot. Sono disponibili sul GitHub Marketplace e possono essere installate sia a livello individuale che organizzativo. Le extensions si integrano direttamente con Copilot Chat, permettendo agli sviluppatori di interagire con strumenti esterni senza uscire dal proprio IDE o dal browser.

Architettura delle Extensions

Le Copilot Extensions sono costruite come GitHub Apps, il che garantisce compatibilità' cross-platform e un modello di autenticazione e autorizzazione robusto. Quando un utente invoca un'extension tramite Copilot Chat, la richiesta viene instradata attraverso l'infrastruttura GitHub verso l'endpoint dell'extension, che elabora la richiesta e restituisce una risposta.

Flusso di una Copilot Extension

StepAttoreAzioneDettaglio
1UtenteInvoca l'extension in chat@extension-name come posso...?
2GitHubAutentica la richiestaVerifica permessi utente e app
3GitHubInoltra all'endpointHTTP POST al server dell'extension
4ExtensionElabora la richiestaChiama API esterne, analizza dati
5ExtensionGenera rispostaTesto, codice, link, azioni
6GitHubRestituisce rispostaFormattata nella chat di Copilot

Tipi di Extensions

GitHub distingue due tipologie principali di extensions, ciascuna con caratteristiche e complessità' di implementazione diverse.

Full Extensions (Agents)

  • Applicazioni complete con logica server-side
  • Possono chiamare API esterne
  • Gestiscono stato e sessioni
  • Supportano flussi complessi multi-step
  • Richiedono infrastruttura di hosting propria
  • Maggiore flessibilità' e potenza
  • Tempo di sviluppo: settimane/mesi

Skillsets (Lightweight)

  • Estensioni leggere e task-specific
  • Definite tramite configurazione, poco codice
  • Focus su una singola capacità'
  • Veloci da costruire e deployare
  • Nessuna infrastruttura complessa richiesta
  • Ideali per automazioni semplici
  • Tempo di sviluppo: ore/giorni

Skillsets: Estensioni Leggere

Gli skillsets sono il modo più' semplice per estendere Copilot con funzionalità' personalizzate. Sono ideali per task specifici e ripetitivi che non richiedono logica complessa. Uno skillset e' essenzialmente una definizione di tool che Copilot può' utilizzare per rispondere a richieste specifiche.

Struttura di uno Skillset

Definizione Skillset - Database Query Helper
{
  "name": "db-query-helper",
  "description": "Helps developers write and optimize SQL queries for PostgreSQL",
  "version": "1.0.0",
  "skills": [
    {
      "name": "explain-query",
      "description": "Analyze and explain a SQL query step by step",
      "parameters": {
        "query": {
          "type": "string",
          "description": "The SQL query to analyze"
        },
        "database": {
          "type": "string",
          "description": "Target database type",
          "enum": ["postgresql", "mysql", "sqlite"],
          "default": "postgresql"
        }
      }
    },
    {
      "name": "optimize-query",
      "description": "Suggest optimizations for a SQL query including index recommendations",
      "parameters": {
        "query": {
          "type": "string",
          "description": "The SQL query to optimize"
        },
        "table_info": {
          "type": "string",
          "description": "Table schemas and current indexes"
        },
        "expected_rows": {
          "type": "number",
          "description": "Expected number of rows in result"
        }
      }
    },
    {
      "name": "generate-migration",
      "description": "Generate a database migration script from a description",
      "parameters": {
        "description": {
          "type": "string",
          "description": "Description of schema changes"
        },
        "format": {
          "type": "string",
          "description": "Migration format",
          "enum": ["flyway", "liquibase", "prisma", "raw-sql"],
          "default": "flyway"
        }
      }
    }
  ]
}

Casi d'Uso per Skillsets

Skillsets Comuni per Team di Sviluppo

SkillsetFunzioneTriggerOutput
Code FormatterFormatta codice secondo standard aziendali@formatter format this codeCodice formattato + diff
Regex BuilderGenera regex da descrizione naturale@regex validate Italian fiscal codePattern regex + test cases
API Mock GeneratorGenera mock data da schema OpenAPI@mock generate 10 usersJSON con dati realistici
Changelog WriterGenera changelog da commit history@changelog since v2.1.0Markdown changelog formattato
Dependency CheckerVerifica dipendenze outdated e vulnerabili@deps check this projectReport con versioni e CVE
i18n HelperGenera traduzioni per chiavi mancanti@i18n translate to ItalianFile JSON/YAML con traduzioni

GitHub Apps Integration

Le Copilot Extensions complete sono costruite come GitHub Apps. Questo significa che ereditano tutto il modello di sicurezza, autenticazione e autorizzazione delle GitHub Apps, garantendo un'integrazione sicura e controllabile.

Autenticazione e Autorizzazione

Modello di Sicurezza delle Extensions

LivelloMeccanismoDescrizione
App-levelJWT (JSON Web Token)Identifica l'app stessa presso GitHub
Installation-levelInstallation Access TokenToken specifico per l'installazione nell'org
User-levelOAuth User Access TokenAzioni per conto dell'utente specifico
PermissionsGranular permissionsAccesso solo alle risorse necessarie (repo, issues, PRs)
WebhooksHMAC-SHA256 signatureVerifica autenticita' degli eventi ricevuti

Permessi Richiesti

Ogni extension dichiara i permessi di cui ha bisogno. L'utente o l'admin dell'organizzazione deve approvarli esplicitamente prima dell'installazione. Il principio di minimo privilegio deve guidare la scelta dei permessi.

Manifest GitHub App - Permessi per Extension
{
  "name": "Copilot DB Assistant",
  "description": "Database query helper for Copilot Chat",
  "url": "https://db-assistant.example.com",
  "hook_attributes": {
    "url": "https://db-assistant.example.com/webhooks"
  },
  "redirect_url": "https://db-assistant.example.com/auth/callback",
  "public": true,
  "default_events": [
    "issues",
    "pull_request"
  ],
  "default_permissions": {
    "contents": "read",
    "issues": "write",
    "pull_requests": "read",
    "metadata": "read"
  },
  "copilot_agent": {
    "url": "https://db-assistant.example.com/copilot/agent",
    "description": "Helps with database queries and migrations"
  }
}

Integrazione MCP nel Contesto delle Extensions

Il Model Context Protocol (MCP) e' un'alternativa complementare alle Copilot Extensions per collegare strumenti esterni a Copilot. Mentre le extensions seguono il modello GitHub Apps, MCP offre un protocollo standardizzato per la connessione di tool e fonti di dati.

GitHub MCP Registry

Il GitHub MCP Registry e' un servizio di discovery curato per server MCP. Funziona come un catalogo che permette di trovare e installare rapidamente server MCP verificati, riducendo il rischio di integrazioni non sicure.

Confronto: Extensions vs MCP Servers

AspettoCopilot ExtensionsMCP Servers
PiattaformaGitHub MarketplaceMCP Registry + configurazione locale
AutenticazioneGitHub OAuth / App tokensVaria (API key, OAuth, none)
HostingServer esterno (cloud)Locale (stdio) o remoto (HTTP/SSE)
Complessità' setupMedia (GitHub App)Bassa (config file)
Cross-platformTutti gli ambienti CopilotPrincipalmente IDE (VS Code)
GovernanceGitHub Marketplace reviewResponsabilità' dell'utente/org
Caso d'usoIntegrazioni SaaS, workflow complessiTool locali, database, file system
DistribuzionePubblica (Marketplace)Privata o pubblica (Registry)

Toolsets: Raggruppare i Tool MCP

I toolsets sono un meccanismo per raggruppare tool MCP correlati sotto un unico namespace. Questo semplifica la gestione quando si hanno molti server MCP attivi contemporaneamente, permettendo di abilitare/disabilitare gruppi di tool con una singola operazione.

.vscode/mcp.json - Configurazione con Toolsets
{
  "servers": {
    "development-tools": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@dev-tools/mcp-server"],
      "toolsets": {
        "database": {
          "description": "Database management tools",
          "tools": ["query", "migrate", "seed", "backup"]
        },
        "testing": {
          "description": "Testing utilities",
          "tools": ["generate-test", "run-test", "coverage-report"]
        },
        "documentation": {
          "description": "Documentation generation",
          "tools": ["generate-docs", "update-readme", "create-adr"]
        }
      }
    },
    "cloud-services": {
      "type": "remote",
      "url": "https://cloud-mcp.example.com/sse",
      "toolsets": {
        "aws": {
          "description": "AWS service management",
          "tools": ["s3-upload", "lambda-deploy", "cloudwatch-logs"]
        },
        "monitoring": {
          "description": "Monitoring and alerting",
          "tools": ["check-health", "get-metrics", "create-alert"]
        }
      }
    }
  }
}

Third-Party Agents

Una delle evoluzioni più' significative dell'ecosistema Copilot e' l'integrazione di agenti di terze parti direttamente nella piattaforma. Questi agenti portano le capacità' di modelli AI alternativi all'interno dell'esperienza Copilot.

Agenti Disponibili

Third-Party Agents in Copilot

AgenteProviderSpecializzazioneDisponibilità'Modello
ClaudeAnthropicAnalisi codice approfondita, refactoring, documentazionePro+ / EnterpriseClaude Sonnet 4
CodexOpenAIGenerazione codice, completamenti avanzatiPro+ / EnterpriseCodex / o3-mini
GeminiGoogleComprensione multimodale, contesto lungoPro+ / EnterpriseGemini 2.5 Pro

Quando Usare Ciascun Agente

ScenarioAgente ConsigliatoMotivazione
Refactoring codebase legacyClaudeEccellente nell'analisi di codice complesso e nel proporre ristrutturazioni graduali
Generazione boilerplate rapidaCopilot nativo (GPT-4)Ottimizzato per completamenti veloci e scaffolding
Analisi screenshot UIGeminiComprensione multimodale per analizzare immagini di interfacce
Debugging algoritmico complessoCodex / o3-miniForte nel ragionamento logico e nella risoluzione di problemi algoritmici
Documentazione tecnica dettagliataClaudeProduce testo tecnico di alta qualità' con contesto lungo
Migrazione tra frameworkClaude o Copilot nativoComprensione profonda dei pattern di diversi framework

Nota sulla Disponibilità'

Gli agenti di terze parti sono attualmente in public preview e disponibili solo per i piani Pro+ e Enterprise. La disponibilità' e i modelli specifici possono variare nel tempo man mano che nuovi provider vengono integrati nella piattaforma.

L'utilizzo degli agenti di terze parti consuma premium requests dal proprio budget mensile. Richieste a modelli avanzati possono consumare più' premium requests rispetto a richieste al modello base di Copilot.

Costruire la Propria Copilot Extension

Se le estensioni disponibili sul Marketplace non coprono le esigenze specifiche del tuo team, puoi costruire la tua Copilot Extension. Il processo richiede la creazione di una GitHub App con un endpoint server che gestisca le richieste di Copilot.

Prerequisiti

Cosa Serve per Costruire un'Extension

  • Account GitHub: Con accesso alla creazione di GitHub Apps
  • Server web: Per ospitare l'endpoint dell'extension (Node.js, Python, Go, ecc.)
  • Dominio HTTPS: L'endpoint deve essere accessibile via HTTPS
  • Conoscenza delle GitHub Apps API: Per gestire autenticazione e webhook
  • Copilot Extensions SDK: SDK ufficiale per semplificare lo sviluppo

Architettura di un'Extension

Architettura Extension - Diagramma Testuale
# Architettura di una Copilot Extension

                    GitHub Infrastructure
                    +-------------------+
                    |                   |
  User in IDE ---> | Copilot Chat      |
  "@my-ext help"   | (message router)  |
                    |                   |
                    +--------+----------+
                             |
                    HTTP POST (authenticated)
                             |
                    +--------v----------+
                    |                   |
                    | Your Extension    |
                    | Server            |
                    |                   |
                    | +---------------+ |
                    | | Request       | |
                    | | Handler       | |
                    | +-------+-------+ |
                    |         |         |
                    | +-------v-------+ |
                    | | Business      | |
                    | | Logic         | |
                    | +-------+-------+ |
                    |         |         |
                    | +-------v-------+ |
                    | | External      | |
                    | | Services      | |
                    | | (DB, API,     | |
                    | |  tools)       | |
                    | +---------------+ |
                    |                   |
                    +--------+----------+
                             |
                    HTTP Response (streaming)
                             |
                    +--------v----------+
                    |                   |
                    | Copilot Chat      |
                    | (rendered to      |
                    |  user)            |
                    |                   |
                    +-------------------+

Implementazione Base con Node.js

server.ts - Extension Server (Node.js + Express)
import express from 'express';
import { Octokit } from '@octokit/rest';
import { createNodeMiddleware } from '@octokit/webhooks';
import { verifyRequestByKeyId } from '@copilot-extensions/preview-sdk';

const app = express();
app.use(express.json());

// Endpoint principale per Copilot Chat
app.post('/copilot/agent', async (req, res) => {
  try {
    // 1. Verifica autenticita' della richiesta
    const signature = req.headers['github-public-key-signature'] as string;
    const keyId = req.headers['github-public-key-identifier'] as string;
    const body = JSON.stringify(req.body);

    const isValid = await verifyRequestByKeyId(body, signature, keyId, {
      token: process.env.GITHUB_TOKEN!
    });

    if (!isValid) {
      return res.status(401).json({ error: 'Invalid signature' });
    }

    // 2. Estrai il messaggio dell'utente
    const messages = req.body.messages;
    const lastMessage = messages[messages.length - 1];
    const userQuery = lastMessage.content;

    // 3. Elabora la richiesta in base al contenuto
    const response = await processQuery(userQuery, req.body);

    // 4. Restituisci risposta in streaming (SSE format)
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');

    // Invia la risposta come stream di eventi
    res.write(`data: ${JSON.stringify({
      choices: [{
        index: 0,
        delta: {
          role: 'assistant',
          content: response
        }
      }]
    })}\n\n`);

    res.write('data: [DONE]\n\n');
    res.end();

  } catch (error) {
    console.error('Extension error:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

async function processQuery(
  query: string,
  context: any
): Promise<string> {
  // Logica personalizzata dell'extension
  // Qui puoi chiamare database, API esterne, ecc.

  if (query.includes('status')) {
    return await getSystemStatus();
  }

  if (query.includes('deploy')) {
    return await getDeploymentInfo();
  }

  if (query.includes('metrics')) {
    return await getProjectMetrics();
  }

  return `Ciao! Sono l'extension personalizzata del team.
Posso aiutarti con:
- **status**: Stato attuale dei servizi
- **deploy**: Informazioni sull'ultimo deployment
- **metrics**: Metriche del progetto

Come posso aiutarti?`;
}

async function getSystemStatus(): Promise<string> {
  // Esempio: chiama un health check endpoint
  const services = ['api', 'database', 'cache', 'queue'];
  const results = await Promise.all(
    services.map(async (service) => {
      try {
        const response = await fetch(
          `https://monitoring.example.com/health/${service}`
        );
        const data = await response.json();
        return `- **${service}**: ${data.status} (uptime: ${data.uptime})`;
      } catch {
        return `- **${service}**: UNREACHABLE`;
      }
    })
  );

  return `## System Status\n\n${results.join('\n')}`;
}

async function getDeploymentInfo(): Promise<string> {
  // Esempio: informazioni dall'ultimo deploy
  return `## Last Deployment
- **Version**: v2.4.1
- **Environment**: production
- **Time**: 2 hours ago
- **Status**: Successful
- **Deployed by**: CI/CD Pipeline
- **Commit**: abc1234`;
}

async function getProjectMetrics(): Promise<string> {
  // Esempio: metriche dal sistema di monitoring
  return `## Project Metrics (Last 24h)
- **Requests**: 125,430
- **Error Rate**: 0.12%
- **p95 Latency**: 245ms
- **Active Users**: 3,421
- **CPU Usage**: 45%
- **Memory**: 62%`;
}

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Extension server running on port ${PORT}`);
});

Testing dell'Extension

test/extension.test.ts - Test dell'Extension
import request from 'supertest';
import { app } from '../server';

describe('Copilot Extension', () => {
  describe('POST /copilot/agent', () => {
    it('should respond to status query', async () => {
      const response = await request(app)
        .post('/copilot/agent')
        .set('Content-Type', 'application/json')
        .send({
          messages: [
            {
              role: 'user',
              content: 'What is the current status?'
            }
          ]
        });

      expect(response.status).toBe(200);
      expect(response.headers['content-type']).toContain('text/event-stream');
    });

    it('should handle unknown queries gracefully', async () => {
      const response = await request(app)
        .post('/copilot/agent')
        .send({
          messages: [
            {
              role: 'user',
              content: 'random question'
            }
          ]
        });

      expect(response.status).toBe(200);
      // Should return help message
    });

    it('should reject unauthenticated requests', async () => {
      // Test without proper GitHub signature headers
      const response = await request(app)
        .post('/copilot/agent')
        .set('github-public-key-signature', 'invalid')
        .set('github-public-key-identifier', 'invalid')
        .send({
          messages: [{ role: 'user', content: 'test' }]
        });

      expect(response.status).toBe(401);
    });
  });
});

Pubblicazione sul Marketplace

Processo di Pubblicazione

StepAzioneRequisitiTempo Stimato
1Crea GitHub AppAccount GitHub, dominio HTTPS1 ora
2Implementa endpointServer con SDK Copilot Extensions1-4 settimane
3Test localeInstallazione privata dell'app1-2 giorni
4DocumentazioneREADME, examples, API docs2-3 giorni
5Submit per reviewListing Marketplace completo1 giorno
6Review GitHubCompliance con le guidelines3-10 giorni
7PubblicazioneApprovazione ottenutaImmediata

Categorie di Extensions Popolari

Il GitHub Marketplace offre extensions organizzate per categoria. Ecco le categorie più' popolari e le tipologie di extensions disponibili.

Categorie Principali del Marketplace

CategoriaEsempiValore Aggiunto
Code AnalysisLinter, security scanner, complexity analyzerIdentifica problemi di qualità' e sicurezza nel codice
DatabaseQuery builder, schema visualizer, migration helperGestione database integrata nella chat
Cloud & DevOpsAWS helper, Kubernetes manager, CI/CD statusOperazioni cloud senza uscire dall'IDE
TestingTest generator, coverage reporter, E2E runnerAccelera la creazione e l'esecuzione dei test
DocumentationAPI doc generator, diagram creator, README builderDocumentazione automatica e aggiornata
Project ManagementJira integration, sprint planner, estimation helperConnessione tra codice e gestione progetto
MonitoringSentry, DataDog, PagerDuty integrationsVisibilità' su errori e performance nella chat
DesignFigma integration, color palette helper, icon finderBridge tra design e implementazione

Best Practices per Extension Development

Da Fare

  • Risposte veloci (timeout < 30s)
  • Gestione errori graceful
  • Documentazione chiara e completa
  • Permessi minimi necessari
  • Logging strutturato per debug
  • Rate limiting interno
  • Test automatizzati completi
  • Versionamento semantico
  • Risposta in formato Markdown
  • Suggerire next steps all'utente

Da Evitare

  • Risposte troppo lunghe (> 4000 char)
  • Operazioni distruttive senza conferma
  • Esporre dati sensibili nelle risposte
  • Richiedere permessi non necessari
  • Ignorare la verifica della firma
  • Risposte senza contesto o struttura
  • Dipendenze non mantenute
  • Mancanza di error messages chiari
  • Chiamate API sincrone bloccanti
  • Mancanza di health check endpoint

Pattern di Risposta Consigliato

Le risposte delle extensions dovrebbero seguire un pattern consistente per fornire un'esperienza utente uniforme. Ecco il formato raccomandato:

  1. Titolo: Heading chiaro che descrive il risultato
  2. Risultato: Dati richiesti formattati in modo leggibile
  3. Contesto: Informazioni aggiuntive utili per l'interpretazione
  4. Next Steps: Suggerimenti su azioni successive possibili

Sicurezza delle Extensions

La sicurezza e' una priorità' quando si utilizzano o si costruiscono extensions. Ogni extension ha accesso potenziale a dati sensibili e deve essere trattata con la stessa attenzione riservata a qualsiasi integrazione di terze parti.

Checklist Sicurezza per Extensions

AreaVerificaRischio se Ignorato
AutenticazioneVerifica sempre la firma GitHub delle richiesteRichieste fraudolente elaborate
AutorizzazioneControlla i permessi dell'utente prima di agireEscalation di privilegi
Input validationValida tutti i parametri in ingressoInjection attacks
SecretsMai esporre token/chiavi nelle risposteLeak di credenziali
Rate limitingImplementa limiti per utente e per IPDenial of service
LoggingLog senza dati sensibili (no PII, no token)Data breach via log
HTTPSSolo comunicazioni criptateMan-in-the-middle attacks
DependenciesAudit regolare delle dipendenzeSupply chain attacks

Conclusione

L'ecosistema delle Copilot Extensions trasforma GitHub Copilot da un assistente di codifica isolato a un hub centralizzato per l'intero workflow di sviluppo. Che si tratti di collegare database, servizi cloud, strumenti di monitoring o agenti AI di terze parti, le extensions permettono di portare tutto il contesto necessario direttamente nella conversazione con Copilot.

Per i team, le extensions rappresentano un'opportunità' per automatizzare workflow ripetitivi e centralizzare le informazioni. Per gli sviluppatori individuali, sono un modo per personalizzare l'esperienza Copilot con strumenti specifici per il proprio dominio.

Nel prossimo e ultimo articolo della serie, affronteremo il tema cruciale della sicurezza e dell'uso responsabile di Copilot, esplorando le protezioni integrate, le linee guida per la privacy dei dati e le best practices per un utilizzo etico e sicuro dell'AI nello sviluppo software.

Progresso della Serie

#ArticoloStato
1Foundation e Mindset✅
2Ideazione e Requisiti✅
3Architettura Backend/Frontend✅
4Struttura del Codice✅
5Prompt Engineering✅
6Testing e qualità'✅
7Documentazione✅
8Deploy e DevOps✅
9Evoluzione✅
10Coding Agent✅
11Code Review✅
12Copilot Edits✅
13GitHub Spark✅
14Copilot Spaces✅
15Modelli AI✅
16Personalizzazione Avanzata✅
17Enterprise e Business✅
18Extensions e Marketplace📍
19Sicurezza e Uso Responsabile◻

Prova Questi Strumenti

Strumenti gratuiti correlati a questo argomento.

Commenti

Caricamento commenti...

Accedi per commentare

Discuti questo articolo nella community

Unisciti al gruppo Telegram per discutere con altri sviluppatori, fare domande e condividere le tue esperienze.

Ti è piaciuto questo articolo?

Esplora altri contenuti sul blog o scopri i miei progetti