Développement d'extensions
Apprenez à créer des extensions pour étendre les fonctionnalités de Volt
Guide de développement d'extensions
Créez des extensions puissantes pour Volt
Créez des extensions qui s'intègrent parfaitement à l'architecture ultra-rapide de Volt. Les extensions sont distribuées sous forme de fichiers ZIP et peuvent être partagées via le registre officiel.
Bienvenue dans le guide de développement d'extensions de Volt ! Ce guide vous aidera à créer vos propres extensions pour étendre les capacités de Volt.
Modèle de sécurité
Les extensions communautaires s'exécutent dans un sandbox Web Worker avec une CSP stricte. eval, XMLHttpRequest, WebSocket et l'accès DOM direct sont bloqués. Les appels réseau passent par un proxy gardé par permissions. Consultez Sandbox & permissions avant de publier.
SDK et CLI
Installez le SDK officiel et l'outil CLI pour commencer :
npm install @voltlaunchrr/plugin-api
npm install -g @voltlaunchrr/plugin-clibun add @voltlaunchrr/plugin-api
bun add -g @voltlaunchrr/plugin-clipnpm add @voltlaunchrr/plugin-api
pnpm add -g @voltlaunchrr/plugin-cliLe CLI fournit scaffolding, validation et packaging :
volt-plugin init my-extension # Créer une nouvelle extension
volt-plugin test # Valider le manifeste, l'interface et les types
volt-plugin publish # Empaqueter et générer l'entrée du registreDémarrage rapide
Créez le répertoire de l'extension
Utilisez le CLI ou créez manuellement :
volt-plugin init my-extension
cd my-extensionCréez manifest.json
Chaque extension requiert un fichier manifeste :
{
"id": "my-extension",
"name": "My Extension",
"version": "1.0.0",
"description": "Une extension Volt personnalisée",
"author": { "name": "Votre nom" },
"main": "index.ts",
"category": "utilities",
"minVoltVersion": "0.4.0",
"permissions": []
}Implémentez votre plugin
Créez le fichier principal du plugin :
class MyExtensionPlugin implements Plugin {
id = 'my-extension';
name = 'My Extension';
description = 'Une extension Volt personnalisée';
enabled = true;
canHandle(context: PluginContext): boolean {
return context.query.toLowerCase().startsWith('my ');
}
match(context: PluginContext): PluginResult[] {
const { PluginResultType } = window.VoltAPI.types;
const query = context.query.slice(3); // Retire "my "
return [{
id: '1',
type: PluginResultType.Info,
title: `Process: ${query}`,
subtitle: 'Appuyez sur Entrée pour exécuter',
icon: '⚡',
score: 100,
data: { query }
}];
}
async execute(result: PluginResult): Promise<void> {
window.VoltAPI.notify(`Exécuté avec : ${result.data?.query}`, 'success');
}
}
export default MyExtensionPlugin;Testez votre extension (mode dev)
- Ouvrez Volt → Paramètres → Extensions
- Cliquez sur « Lier une extension de dev »
- Sélectionnez le dossier de votre extension
- Tapez votre mot-clé déclencheur pour tester !
Rechargement à chaud
Modifiez votre code, sauvegardez, et appuyez sur Ctrl+R pour rafraîchir. Aucun packaging requis !
Voir Workflow de développement pour plus d'options.
Architecture des extensions
Volt propose un système d'extensions hybride avec deux couches :
Extensions frontend
TypeScript — Gèrent l'UI et les interactions utilisateur. Idéales pour calculatrices, recherches web, générateurs.
Plugins backend
Rust — Gèrent les intégrations système. Idéals pour scanners de jeux, moniteurs système, opérations fichiers.
Extensions frontend
- Écrites en TypeScript
- S'exécutent dans le contexte navigateur
- Accès à
window.VoltAPIpour les utilitaires - Timeout de 500 ms par requête
- Idéales pour : calculatrices, recherches web, générateurs, convertisseurs
class MyPlugin implements Plugin {
id = 'my-plugin';
name = 'My Plugin';
description = 'Fait quelque chose d\'utile';
enabled = true;
canHandle(context: PluginContext): boolean {
return context.query.startsWith('my ');
}
match(context: PluginContext): PluginResult[] {
const { PluginResultType } = window.VoltAPI.types;
return [{
id: '1',
type: PluginResultType.Info,
title: 'Résultat',
score: 100
}];
}
async execute(result: PluginResult): Promise<void> {
await window.VoltAPI.utils.copyToClipboard('copié !');
window.VoltAPI.notify('Terminé !', 'success');
}
}
export default MyPlugin;Plugins backend
- Écrits en Rust
- Accès système complet
- Performance native
- Idéals pour : scanners de jeux, moniteurs système, opérations fichiers
use async_trait::async_trait;
use crate::core::traits::Plugin;
pub struct MyBackendPlugin {
enabled: bool,
}
#[async_trait]
impl Plugin for MyBackendPlugin {
fn id(&self) -> &str { "my-backend-plugin" }
fn name(&self) -> &str { "My Backend Plugin" }
fn description(&self) -> &str { "Intégration système" }
fn is_enabled(&self) -> bool { self.enabled }
fn required_capabilities(&self) -> Vec<String> { vec![] }
async fn initialize(&mut self) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
async fn shutdown(&mut self) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
}Diagramme d'architecture
┌─────────────────────────────────────────────────────────┐
│ Frontend (React/TypeScript) │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Extension Loader │ │
│ │ • Charge les extensions depuis ZIP ou dossiers │ │
│ │ • Compile TypeScript → JavaScript │ │
│ │ • Injecte VoltAPI │ │
│ └───────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Plugin Registry │ │
│ │ • Gère tous les plugins (intégrés + extensions) │ │
│ │ • Route les requêtes vers les plugins │ │
│ │ • Gère les timeouts de 500 ms │ │
│ └───────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Plugin │ │Extension│ │Extension│ │ DEV │ │
│ │ intégré │ │ A │ │ B │ │Extension│ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────────────────┘
↕ Tauri IPC
┌─────────────────────────────────────────────────────────┐
│ Backend (Rust/Tauri) │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Commandes de gestion d'extensions │ │
│ │ • install_extension() / uninstall_extension() │ │
│ │ • link_dev_extension() / unlink_dev_extension() │ │
│ │ • toggle_extension() / refresh_dev_extension() │ │
│ │ • fetch_extension_registry() │ │
│ └───────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘VoltAPI — API globale
Toutes les extensions ont accès à l'objet global window.VoltAPI :
// Types
window.VoltAPI.types.PluginResultType; // Enum des types de résultat
// Utilitaires
window.VoltAPI.utils.copyToClipboard(text); // Copier dans le presse-papiers
window.VoltAPI.utils.openUrl(url); // Ouvrir une URL dans le navigateur
window.VoltAPI.utils.fuzzyScore(query, str); // Correspondance floue
window.VoltAPI.utils.formatNumber(num); // Formater des nombres
// Communication backend
window.VoltAPI.invoke(command, args); // Appeler des commandes Tauri
// Événements
window.VoltAPI.events.emit(event, data); // Émettre un événement personnalisé
window.VoltAPI.events.on(event, handler); // S'abonner aux événements
// Notifications
window.VoltAPI.notify(message, type); // Afficher une notificationRéférence complète de l'API
Voir la Référence API pour la documentation complète de VoltAPI.
Types de résultats de plugin
Les extensions peuvent renvoyer différents types de résultats :
Prop
Type
Distribution d'extensions
Les extensions sont distribuées sous forme de fichiers ZIP via GitHub Releases :
- Empaquetez les fichiers de votre extension dans un ZIP
- Créez une GitHub Release avec le ZIP en asset
- Soumettez au registre officiel pour la découvrabilité
my-extension-v1.0.0.zip
├── manifest.json
├── index.ts
├── types.ts
└── utils/
└── helpers.tsVoir le Guide de publication pour des instructions détaillées.
Exemple complet
Voici une extension complète, prête pour la production :
// Extension Greeting
// Répond aux requêtes "hello" avec des salutations personnalisées
interface Plugin {
id: string;
name: string;
description: string;
enabled: boolean;
canHandle(context: PluginContext): boolean;
match(context: PluginContext): PluginResult[];
execute(result: PluginResult): Promise<void>;
}
interface PluginContext {
query: string;
settings?: Record<string, unknown>;
}
interface PluginResult {
id: string;
type: any;
title: string;
subtitle?: string;
icon?: string;
score: number;
data?: Record<string, unknown>;
}
const TRIGGERS = ["hello", "hi", "hey", "greet"];
class GreetingPlugin implements Plugin {
id = "greeting";
name = "Greeting";
description = "Salutations amicales pour tous";
enabled = true;
canHandle(context: PluginContext): boolean {
const query = context.query.toLowerCase().trim();
return TRIGGERS.some((t) => query.startsWith(t));
}
match(context: PluginContext): PluginResult[] {
const { PluginResultType } = window.VoltAPI.types;
const query = context.query.trim();
// Extraire le nom s'il est fourni (ex. "hello John")
const parts = query.split(/\s+/);
const name = parts.length > 1 ? parts.slice(1).join(" ") : "friend";
const greetings = [`Hello, ${name}! 👋`, `Hey there, ${name}! ✨`, `Greetings, ${name}! 🌟`];
return greetings.map((greeting, i) => ({
id: `greeting-${i}`,
type: PluginResultType.Info,
title: greeting,
subtitle: "Appuyez sur Entrée pour copier",
icon: "👋",
score: 100 - i,
data: { greeting },
}));
}
async execute(result: PluginResult): Promise<void> {
const greeting = result.data?.greeting as string;
const success = await window.VoltAPI.utils.copyToClipboard(greeting);
if (success) {
window.VoltAPI.notify("Salutation copiée !", "success");
}
}
}
export default GreetingPlugin;{
"id": "greeting",
"name": "Greeting",
"version": "1.0.0",
"description": "Salutations amicales pour tous",
"author": { "name": "Votre nom" },
"main": "index.ts",
"category": "utilities",
"keywords": ["hello", "greeting", "friendly"],
"minVoltVersion": "0.4.0",
"permissions": ["clipboard"]
}Étapes suivantes
Référence API
Documentation complète de VoltAPI et de l'interface Plugin
Workflow de développement
Configurez le développement local et les tests
Exemples de plugins
Implémentations d'extensions concrètes
Bonnes pratiques
Conseils pour créer d'excellentes extensions
Guide de publication
Partagez vos extensions avec la communauté