// documentation officielleofficial documentation

Guide Ultime
PulsiForms

Ultimate Guide
PulsiForms

Tout ce qu'il faut pour écrire du PowerShell / WinForms compatible PulsiForms — du premier contrôle posé sur le canvas jusqu'aux traitements asynchrones qui ne gèlent jamais l'interface. Chaque commande, chaque signature et chaque exemple de ce guide est vérifié directement dans le code source (pfstdlib_ps1.js, export.js, psguard.js).
Everything you need to write PulsiForms-compatible PowerShell / WinForms — from your first control on the canvas to async work that never freezes the UI. Every command, signature and example in this guide is verified directly against the source code (pfstdlib_ps1.js, export.js, psguard.js).
v55 Deep AI WinForms .NET PowerShell 5.1+ PF-Script Stdlib v2.0
🤖
Une question pendant la lecture ? L'assistant IA local de l'application PulsiForms fonctionne hors-ligne : il connaît toutes les commandes PF-Script, explique chaque paramètre et propose des exemples de code prêts à coller. Demandez-lui « explique Start-PF » ou « exemple de Validate-PF ». A question while reading? The local AI assistant built into the PulsiForms app works offline: it knows every PF-Script command, explains each parameter and offers ready-to-paste code examples. Ask it "explain Start-PF" or "Validate-PF example".
🚀
Jamais ouvert PulsiForms ? Commencez par le tutoriel pas-à-pas « Crée ta première application » : 6 étapes guidées pour construire un vrai outil Windows en 16 minutes, puis revenez ici pour approfondir. New to PulsiForms? Start with the step-by-step tutorial "Build your first app": 6 guided steps to build a real Windows tool in 16 minutes, then come back here to go deeper.

🔄 Comment PulsiForms génère le PS1How PulsiForms generates the PS1

PulsiForms n'est pas un éditeur de texte : c'est un compilateur visuel. Vos actions graphiques (drag & drop, propriétés, code d'événement) sont transformées en un script PowerShell autonome.

PulsiForms is not a text editor: it is a visual compiler. Your graphical actions (drag & drop, properties, event code) are turned into a self-contained PowerShell script.

🖱️
Canvas
Drag & Drop
🗄️
state.js
Modèle JSJS model
⚙️
export.js
GénérateurGenerator
📄
Script .ps1
+ Stdlib+ Stdlib

À l'export, PulsiForms injecte automatiquement la bibliothèque PF-Script Stdlib (issue de pfstdlib_ps1.js) en tête du script. Vous disposez ainsi de fonctions prêtes à l'emploi (Show-PF, Get-PF, Start-PF…) sans rien réécrire.

On export, PulsiForms automatically injects the PF-Script Stdlib (from pfstdlib_ps1.js) at the top of the script. You get ready-to-use functions (Show-PF, Get-PF, Start-PF…) without rewriting anything.

PowerShell généré — exemple ButtonGenerated PowerShell — Button example
# PulsiForms génère ceci automatiquement : $Button_1 = New-Object System.Windows.Forms.Button $Button_1.Text = "Valider" $Button_1.Location = New-Object System.Drawing.Point(50, 80) $Button_1.Size = New-Object System.Drawing.Size(120, 38) # Votre code d'événement est injecté ICI : $Button_1.Add_Click({ ### ← votre code arrive ici ### }) $cp.Controls.Add($Button_1)
💡
Le code écrit dans l'éditeur Code PS est placé à l'intérieur du bloc { ... } de l'événement. PulsiForms s'occupe de la création, du positionnement et du style.The code you write in the Code PS editor is placed inside the event's { ... } block. PulsiForms handles creation, positioning and styling.

« Variable non déclarée » — le piège n°1"Variable not declared" — pitfall #1

L'erreur la plus fréquente vient d'une incompréhension du scope PowerShell. Chaque événement Add_Click({ ... }) est un scriptblock avec son propre scope : une variable créée dans un événement n'existe pas dans un autre.

The most common error comes from misunderstanding PowerShell scope. Each Add_Click({ ... }) event is a scriptblock with its own scope: a variable created in one event does not exist in another.

Ce qui ne marche pas
What doesn't work
# Button_1 Click : $monNom = $TextBox_1.Text # Button_2 Click : $Label_1.Text = $monNom # vide !
La bonne approche
The right approach
# Button_1 Click : $global:monNom = $TextBox_1.Text # Button_2 Click : $Label_1.Text = $global:monNom

# Les 3 scopes à connaîtreThe 3 scopes to know

🌍
$global:
Accessible partout, dans tous les événements. Pour les données partagées entre contrôles.
Accessible everywhere, in every event. For data shared between controls.
📜
$script:
Scope du script entier. Utilisé par PulsiForms pour $script:form et $script:_controls.
Whole-script scope. Used by PulsiForms for $script:form and $script:_controls.
📦
(local)
Variable sans préfixe. Valable uniquement dans le bloc { } courant.
Variable with no prefix. Valid only inside the current { } block.
⚠️
Le nom de variable du contrôle dans le panneau Propriétés est exactement ce qu'il faut écrire. Si le contrôle s'appelle TextBox_3, écrivez $TextBox_3 — pas $TextBox3, pas $tb.The control's variable name in the Properties panel is exactly what to type. If the control is named TextBox_3, write $TextBox_3 — not $TextBox3, not $tb.

# Référencer le formulaireReferencing the form

$script:form
$form.Close() # ❌ $form non défini dans ce scope $script:form.Close() # ✅ toujours $script:form $script:form.Text = "Titre" # ✅ change le titre de la fenêtre

📐 Règles fondamentalesCore rules

Ne pas écrireDon't writeCompatible PulsiFormsPulsiForms compatible
$form.Close()$script:form.Close()
[Windows.Forms.MessageBox]::Show("x")Alert-PF "x" / Show-PF "x"
$maVar = "v" (entre 2 events)$global:maVar = "v"
Write-Host "debug"Show-PF "debug"
Start-Sleep -Seconds 3 (gèle l'UI)Sleep-PF -Ms 3000 / Wait-PF
$script:txt.Text depuis -WorkWrite-PF $script:txt "v" (thread-safe)
Toutes les fonctions *-PF sont thread-safe (gestion automatique de InvokeRequired / .Invoke()) : vous pouvez les appeler depuis un callback async sans crash inter-thread.All *-PF functions are thread-safe (automatic InvokeRequired / .Invoke() handling): you can call them from an async callback without cross-thread crashes.
// le plus importantmost important

Async — ne jamais geler l'interfaceAsync — never freeze the UI

Un traitement long (lecture de fichiers, requête réseau, boucle lourde) exécuté directement dans un Add_Click gèle l'interface : la fenêtre devient blanche, Windows affiche « Ne répond pas ». PulsiForms fournit trois outils pour l'éviter. Choisissez selon ce dont vous avez besoin.

A long task (file reading, network request, heavy loop) run directly inside an Add_Click freezes the UI: the window goes white and Windows shows "Not responding". PulsiForms provides three tools to avoid this. Choose based on what you need.

Mon traitement a-t-il besoin de lire/écrire des contrôles PENDANT son exécution ?Does my task need to read/write controls DURING execution?
├─ NON · tâche de fond, je veux juste le résultat à la finbackground task, I just want the result at the endStart-PF
├─ NON · + je veux un dialog « patientez » avec Annuler+ I want a "please wait" dialog with CancelWait-PF
└─ OUI · boucle courte qui met à jour une ProgressBar en directshort loop updating a ProgressBar liveSleep-PF
🚫
La règle d'or du runspace. Le bloc -Work de Start-PF et Wait-PF s'exécute dans un runspace isolé (autre thread). Il n'a aucun accès à $script: ni aux contrôles. Pour faire entrer des données → paramètre -With @{}. Pour récupérer le résultat → bloc -Then. The runspace golden rule. The -Work block of Start-PF and Wait-PF runs in an isolated runspace (separate thread). It has no access to $script: or controls. To pass data in → -With @{}. To get the result out → the -Then block.
Start-PFTâche de fond non-bloquante, sans dialogNon-blocking background task, no dialogASYNC
Start-PF -Work {…} [-Then {…}] [-Catch {…}] [-With @{}]

-Work ScriptBlock exécuté en arrière-plan (runspace isolé). Reçoit $_shared en argument — qui contient les clés passées via -With. · -Then callback UI au succès, reçoit le résultat de -Work. · -Catch callback UI en cas d'erreur, reçoit le message. · -With hashtable de données injectées dans le runspace.

-Work ScriptBlock run in the background (isolated runspace). Receives $_shared as argument — containing the keys passed via -With. · -Then UI callback on success, receives -Work's result. · -Catch UI callback on error, receives the message. · -With hashtable of data injected into the runspace.

Start-PF
# Lire un gros fichier sans geler la fenêtre $chemin = Get-PF $TextBox_1 Start-PF -Work { param($s) # $s = $_shared $lignes = Get-Content $s.Path return $lignes.Count # transmis à -Then } -With @{ Path = $chemin } -Then { param($r) # $r = résultat Write-PF $Label_1 "$r lignes" Show-PF "Terminé !" -IsSuccess } -Catch { param($err) Alert-PF "Échec : $err" -IsError }
Wait-PFAsync + dialog « patientez » avec spinner & AnnulerAsync + "please wait" dialog with spinner & CancelASYNC→ result
Wait-PF -Work {…} [-Then {…}] [-Catch {…}] [-With @{}] [-Message str] [-Title str] [-NoCancelBtn]

Même moteur que Start-PF, mais affiche un dialog modal avec spinner animé. Le worker doit tester $_shared["_canceled"] pour s'arrêter proprement si l'utilisateur clique Annuler. Retourne le résultat de -Work, ou $null si annulé/erreur.

Same engine as Start-PF, but shows a modal dialog with an animated spinner. The worker must check $_shared["_canceled"] to stop cleanly if the user clicks Cancel. Returns -Work's result, or $null if cancelled/error.

Wait-PF
$result = Wait-PF -Message "Import en cours…" -Work { param($s) foreach ($item in $s.Liste) { if ($s["_canceled"]) { break } # arrêt propre # … traitement lourd ici … } return "Terminé" } -With @{ Liste = $maListe } -Then { param($r) Show-PF $r -IsSuccess }
🔄Sleep-PFPause SYNCHRONE (thread UI) — accès direct à $script:SYNC pause (UI thread) — direct $script: accessSYNC→ bool
Sleep-PF [-Ms int] [-Message str] [-Title str] [-NoCancelBtn] [-End]

Contrairement à Wait-PF, Sleep-PF reste sur le thread UI (boucle DoEvents) : $script: et les contrôles sont accessibles directement dans la boucle appelante. Idéal pour une boucle courte qui met une ProgressBar à jour. Retourne $true si Annuler cliqué. Toujours appeler Sleep-PF -End en fin de boucle (dans un finally).

Unlike Wait-PF, Sleep-PF stays on the UI thread (DoEvents loop): $script: and controls are directly accessible in the calling loop. Ideal for a short loop updating a ProgressBar. Returns $true if Cancel was clicked. Always call Sleep-PF -End at the end of the loop (in a finally).

⚠️
Ne jamais utiliser Sleep-PF à l'intérieur d'un -Work de Start-PF/Wait-PF (runspace séparé). Sleep-PF est réservé au thread UI.Never use Sleep-PF inside a Start-PF/Wait-PF -Work block (separate runspace). Sleep-PF is for the UI thread only.
Sleep-PF — boucle avec ProgressBarSleep-PF — loop with ProgressBar
Lock-PF # verrouille la fenêtre try { for ($i = 1; $i -le 100; $i++) { Set-PF $ProgressBar_1 -Value $i # ✅ accès direct Write-PF $Label_1 "Étape $i/100" # ✅ idem if (Sleep-PF -Ms 80 -Message "Traitement $i/100…") { break } } } finally { Sleep-PF -End # ferme le dialog — garanti même si exception Unlock-PF } Show-PF "Import terminé !" -IsSuccess

# Tableau comparatifComparison table

Start-PFWait-PFSleep-PF
ThreadThreadRunspaceRunspaceUI
Bloquant ?Blocking?Non / NoModalModalBoucle UIUI loop
DialogDialog✅ spinner + Annuler✅ spinner + Annuler
Accès $script:$script: access❌ -With/-Then❌ -With/-Then✅ direct
UsageUsetâche de fondbackground taskopération longue avec attentelong op with waitboucle + ProgressBarloop + ProgressBar

📚 Référence des commandes PF-ScriptPF-Script command reference

Toutes ces fonctions sont injectées automatiquement à l'export. Signatures vérifiées dans pfstdlib_ps1.js (Stdlib v2.0).

All these functions are auto-injected at export. Signatures verified against pfstdlib_ps1.js (Stdlib v2.0).

# Notifications & dialogsNotifications & dialogs

🔔Show-PFToast non-bloquant (3 s)Non-blocking toast (3 s)
Show-PF -Message str [-IsWarning] [-IsError] [-IsSuccess]
Show-PF "Enregistré." -IsSuccess
💬Alert-PFMessageBox thématique modaleThemed modal MessageBox
Alert-PF -Message str [-IsWarning] [-IsError]
Alert-PF "Connexion perdue." -IsError
Ask-PFConfirmation Oui/NonYes/No confirmation→ bool
Ask-PF -Question str → $true (Oui) / $false (Non)
if (Ask-PF "Supprimer cet élément ?") { Clear-PF $DataGridView_1 }
⌨️Read-PFSaisie inline → string ou $nullInline input → string or $null→ string
Read-PF -Prompt str [-Default str]
⚠️
Toujours tester $null -ne $val : l'utilisateur peut cliquer Annuler.Always test $null -ne $val: the user can click Cancel.
$nom = Read-PF "Votre nom :" -Default "Dupont" if ($null -ne $nom) { Write-PF $Label_1 "Bonjour $nom" }

# Contrôles — lire, écrire, remplirControls — read, write, fill

📖Get-PFLit la valeur d'un contrôle (selon son type)Reads a control's value (per type)→ object
Get-PF $Control

TextBox→string · CheckBox→bool · DateTimePicker→DateTime · TrackBar/NumericUpDown→nombre · ComboBox→SelectedItem ou Text · ListBox→SelectedItem · DataGridView→ligne liée (DataBoundItem).

TextBox→string · CheckBox→bool · DateTimePicker→DateTime · TrackBar/NumericUpDown→number · ComboBox→SelectedItem or Text · ListBox→SelectedItem · DataGridView→bound row (DataBoundItem).

$nom = Get-PF $TextBox_1 # string $ok = Get-PF $CheckBox_1 # bool
✏️Write-PFÉcrit dans un contrôleWrites into a controlTHREAD-SAFE
Write-PF $Control $Text [-Append]
Obligatoire pour modifier l'UI depuis un callback -Then de Start-PF/Wait-PF. Gère InvokeRequired automatiquement.Required to update the UI from a Start-PF/Wait-PF -Then callback. Handles InvokeRequired automatically.
Write-PF $Label_1 "Prêt" Write-PF $RichTextBox_1 "Ligne`n" -Append
📋Fill-PFRemplit ListBox / ComboBox / DataGridViewFills ListBox / ComboBox / DataGridView
Fill-PF $Control $Data

Accepte un tableau de strings, de Hashtables ou de PSCustomObjects. Pour un DataGridView, les colonnes sont créées et redimensionnées automatiquement. $null vide le contrôle.

Accepts an array of strings, Hashtables or PSCustomObjects. For a DataGridView, columns are auto-created and resized. $null clears the control.

Fill-PF $ComboBox_1 @("Paris", "Lyon", "Lille") $data = Import-Csv "data.csv" Fill-PF $DataGridView_1 $data
🗑️Clear-PFVide / réinitialise un contrôleEmpties / resets a control
Clear-PF $Control
Clear-PF $TextBox_1 # remet le placeholder (Tag) Clear-PF $DataGridView_1
📊Set-PFMaj numérique thread-safe (ProgressBar, TrackBar, NumericUpDown)Thread-safe numeric updateTHREAD-SAFE
Set-PF $Control [-Value n] [-Add] [-Reset] [-Max]
Set-PF $ProgressBar_1 -Value 75 # à 75 % Set-PF $ProgressBar_1 -Add -Value 10 Set-PF $ProgressBar_1 -Reset
Validate-PFValide UN contrôle (requis / regex / min / max)Validates ONE control→ bool
Validate-PF $Control [-Required] [-Regex str] [-Min n] [-Max n] [-Message str] [-Silent]
ℹ️
S'applique à un seul contrôle à la fois. Pour valider un formulaire, chaînez plusieurs appels.Applies to a single control at a time. To validate a form, chain several calls.
if (-not (Validate-PF $TextBox_1 -Required -Message "Nom requis")) { return } if (-not (Validate-PF $TextBox_2 -Regex "^[^@]+@[^@]+\.[^@]+$" -Message "Email invalide")) { return }
👁️Toggle-PFAfficher / masquer / activer / désactiver (multi-contrôles)Show / hide / enable / disable (multi-control)THREAD-SAFE
Toggle-PF $Controls -Action Show|Hide|Enable|Disable|Toggle
Toggle-PF @($Button_1, $Button_2) -Action Disable Toggle-PF $Panel_1 -Action Hide
🔒Lock-PF / Unlock-PFVerrouille la fenêtre (ou des contrôles précis)Locks the form (or specific controls)
Lock-PF [-Controls @(…)] · Unlock-PF [-Controls @(…)]

Sans argument : verrouille tout le formulaire + curseur sablier. Avec -Controls : seulement les contrôles fournis.

No argument: locks the whole form + wait cursor. With -Controls: only the given controls.

Lock-PF # toute la fenêtre Lock-PF -Controls @($Button_1) # un seul bouton

# Données & fichiersData & files

📁Pick-PFSélecteur fichier / dossier natif WindowsNative Windows file / folder pickerBLOQUANT
Pick-PF [-Mode Open|Save|Folder] [-Filter str] [-Title str] [-InitialPath str] [-DefaultExt str] [-Multi]
⚠️
Tester $null -ne $result — l'utilisateur peut annuler.Test $null -ne $result — the user can cancel.
$f = Pick-PF -Mode Open -Filter "CSV|*.csv|Tous|*.*" $d = Pick-PF -Mode Folder -Title "Choisir un dossier"
💾Save-PF / Load-PFSauvegarde / chargement auto CSV ou TXTAuto CSV/TXT save / load
Save-PF -Data $obj -Path str [-Append] · Load-PF -Path str

Save-PF détecte le format : collection d'objets → CSV (UTF8), sinon → TXT. Load-PF détecte le délimiteur (; ou ,) ou renvoie les lignes brutes.

Save-PF detects the format: object collection → CSV (UTF8), else → TXT. Load-PF detects the delimiter (; or ,) or returns raw lines.

Save-PF -Data $logs -Path "log.txt" -Append $rows = Load-PF -Path "settings.csv"

# Style & navigationStyle & navigation

🎨Style-PFStyle visuel d'un contrôleVisual style for a control
Style-PF $Control -Type Primary|Secondary|Danger|Search
Style-PF $Button_1 -Type Primary Style-PF $Button_2 -Type Danger
Set-IconPF / Set-IconTextPFIcône Segoe MDL2 Assets (code décimal)Segoe MDL2 Assets icon (decimal code)
Set-IconPF $Control -Code int [-Size int] [-TextCtrl $ctrl]
Set-IconTextPF $IconCtrl $TextCtrl -Code int -Text str [-IconSize int]
ℹ️
-Code attend un entier (notation 0xE74D acceptée), pas une chaîne hexadécimale.-Code expects an integer (0xE74D notation works), not a hex string.
Set-IconPF $Button_1 -Code 0xE74D -Size 16 # corbeille
🗂️Go-PFNaviguer vers un onglet (mode multi-pages)Navigate to a tab (multi-page mode)
Go-PF -TabName str
Go-PF "Configuration"

🎛️ Patterns de contrôles courantsCommon control patterns

# TextBox

TextBox
$valeur = Get-PF $TextBox_1 # lire (placeholder → "") Write-PF $TextBox_1 "Nouvelle valeur" # écrire Clear-PF $TextBox_1 # vider / placeholder

# DataGridView

DataGridView
# Remplir depuis un CSV $rows = Import-Csv "clients.csv" Fill-PF $DataGridView_1 $rows # Lire la ligne sélectionnée $ligne = Get-PF $DataGridView_1 # objet lié (DataBoundItem) if ($null -ne $ligne) { Show-PF $ligne.Nom } # Exporter vers CSV (on sauvegarde la source de données) $p = Pick-PF -Mode Save -Filter "CSV|*.csv" if ($null -ne $p) { Save-PF -Data $rows -Path $p }

# ComboBox / CheckBox

ComboBox & CheckBox
Fill-PF $ComboBox_1 @("Faible", "Moyen", "Élevé") $choix = Get-PF $ComboBox_1 # SelectedItem ou Text if (Get-PF $CheckBox_1) { Show-PF "Option activée" }

💼 Cas d'usage completsComplete use cases

# Formulaire avec validationForm with validation

Bouton « Valider » — Click"Submit" button — Click
# 1. Validation champ par champ if (-not (Validate-PF $TextBox_Nom -Required -Message "Le nom est requis")) { return } if (-not (Validate-PF $TextBox_Email -Regex "^[^@]+@[^@]+\.[^@]+$" -Message "Email invalide")) { return } if (-not (Validate-PF $NumericUpDown_Age -Min 18 -Max 120 -Message "Âge entre 18 et 120")) { return } # 2. Lecture + persistance $client = [PSCustomObject]@{ Nom = Get-PF $TextBox_Nom Email = Get-PF $TextBox_Email Age = Get-PF $NumericUpDown_Age } Save-PF -Data @($client) -Path "clients.csv" -Append Show-PF "Client enregistré !" -IsSuccess

# Traitement long non-bloquantLong non-blocking task

Scan de fichiers avec Wait-PFFile scan with Wait-PF
$dossier = Pick-PF -Mode Folder if ($null -eq $dossier) { return } $nb = Wait-PF -Message "Analyse du dossier…" -Work { param($s) (Get-ChildItem $s.Dir -Recurse -File).Count } -With @{ Dir = $dossier } -Then { param($r) Write-PF $Label_1 "$r fichiers trouvés" }

🤖 IA dans PulsiForms — clés Claude & MistralAI in PulsiForms — Claude & Mistral keys

PulsiForms intègre deux assistants en ligne (en plus de l'IA locale hors-ligne). Vous fournissez votre propre clé API — c'est le modèle BYOK (Bring Your Own Key) : vos clés ne sont jamais stockées sur nos serveurs.

PulsiForms ships two online assistants (plus the offline local AI). You provide your own API key — this is the BYOK (Bring Your Own Key) model: your keys are never stored on our servers.

🟣
Claude (Anthropic)
Panneau IA principal, en bas de l'écran. Génération & correction de code PowerShell/PFP. Modèle : claude-sonnet-4-6.
Main AI panel, bottom of the screen. PowerShell/PFP code generation & fixing. Model: claude-sonnet-4-6.
🟢
Mistral AI
PulsiForms Studio (panneau latéral, Ctrl+Shift+P). Wiring rapide & AI Code par contrôle. Modèle : mistral-large-latest.
PulsiForms Studio (side panel, Ctrl+Shift+P). Quick wiring & per-control AI Code. Model: mistral-large-latest.
🔐
Sécurité BYOK. Vos clés sont chiffrées en AES-256-GCM (Web Crypto API) et stockées au choix en session chiffrée ou en mémoire pure (variable de closure, effacée à la fermeture). Elles ne sont jamais écrites dans localStorage, les cookies, le DOM ou la console, et transitent uniquement par en-tête (X-Claude-Key / X-Mistral-Key) vers le proxy. BYOK security. Your keys are encrypted with AES-256-GCM (Web Crypto API) and stored either in an encrypted session or in pure memory (closure variable, wiped on close). They are never written to localStorage, cookies, the DOM or the console, and travel only via header (X-Claude-Key / X-Mistral-Key) to the proxy.

# Créer votre clé Claude (Anthropic)Create your Claude (Anthropic) key

1
Allez sur console.anthropic.com/settings/keys et connectez-vous (ou créez un compte).Go to console.anthropic.com/settings/keys and sign in (or create an account).
2
Cliquez Create Key, nommez-la (ex. « PulsiForms »), puis copiez la clé générée. Elle commence par sk-ant-….Click Create Key, name it (e.g. "PulsiForms"), then copy the generated key. It starts with sk-ant-….
3
Vérifiez votre crédit dans Billing (l'API est facturée à l'usage, indépendamment d'un abonnement Claude.ai).Check your credit under Billing (the API is billed per usage, separately from any Claude.ai subscription).
4
Dans PulsiForms, ouvrez le panneau IA, cliquez sur l'indicateur de clé Claude, collez votre clé sk-ant-… et validez.In PulsiForms, open the AI panel, click the Claude key indicator, paste your sk-ant-… key and confirm.

# Créer votre clé MistralCreate your Mistral key

1
Allez sur console.mistral.ai/api-keys et connectez-vous.Go to console.mistral.ai/api-keys and sign in.
2
Activez la facturation si nécessaire (Billing), puis cliquez Create new key et copiez la clé (format sk-…).Enable billing if needed (Billing), then click Create new key and copy the key (format sk-…).
3
Ouvrez PulsiForms Studio (Ctrl+Shift+P), cliquez sur l'indicateur de clé Mistral, collez votre clé et validez.Open PulsiForms Studio (Ctrl+Shift+P), click the Mistral key indicator, paste your key and confirm.
ClaudeMistral
Créer la cléCreate keyconsole.anthropic.com/settings/keysconsole.mistral.ai/api-keys
FormatFormatsk-ant-…sk-…
Modèle par défautDefault modelclaude-sonnet-4-6mistral-large-latest
Où dans PulsiFormsWhere in PulsiFormsPanneau IA (bas)AI panel (bottom)Studio (Ctrl+Shift+P)

# L'IA locale (hors-ligne)The local AI (offline)

💬
Pas de clé, pas de connexion : l'assistant local intégré à l'application PulsiForms est une base de connaissances embarquée. Il explique chaque commande PF-Script (paramètres, valeur de retour, thread-safety), propose des exemples de code prêts à coller, et peut ouvrir la carte interactive ou cette documentation. Essayez : « explique Wait-PF », « exemple Fill-PF avec un CSV », « différence Start-PF / Sleep-PF ». No key, no connection: the local assistant built into the PulsiForms app is an embedded knowledge base. It explains every PF-Script command (parameters, return value, thread-safety), offers ready-to-paste code examples, and can open the interactive map or this documentation. Try: "explain Wait-PF", "Fill-PF example with a CSV", "Start-PF vs Sleep-PF difference".

🛡️ PS.Guard v3 & Linter internePS.Guard v3 & internal linter

PulsiForms protège votre code à deux niveaux, synchronisés entre eux et avec la Stdlib.

PulsiForms protects your code at two levels, kept in sync with each other and with the Stdlib.

SystèmeSystemQuandWhenSurveilleWatches
Linter PF_*Temps réel, à l'écritureReal-time, while typingCode de l'événement (alias, variables, propriétés)Event code (aliases, variables, properties)
PS.Guard PSG-*Après export du .ps1After .ps1 exportScript complet (sécurité, qualité, perf)Whole script (security, quality, perf)

# PS.Guard v3 — 33 règles, 3 catégoriesrules, 3 categories

🔒
Sécurité (S01–S07)
Invoke-Expression, mots de passe en clair, ConvertTo-SecureString -AsPlainText, Net.WebClient, Set-ExecutionPolicy Bypass, processus cachés, Base64.
Invoke-Expression, plaintext passwords, ConvertTo-SecureString -AsPlainText, Net.WebClient, Set-ExecutionPolicy Bypass, hidden processes, Base64.
⚙️
Qualité (Q01–Q07)
Catch vide, $Error[0] dans catch, if/elseif multiples, alias (60+), cmdlets dépréciées (Get-WmiObjectGet-CimInstance…).
Empty catch, $Error[0] in catch, multiple if/elseif, aliases (60+), deprecated cmdlets (Get-WmiObjectGet-CimInstance…).
WinForms & Perf
Resize via New-Object Size, [CmdletBinding()], faux positifs perf neutralisés par PSGuard-disable/enable.
Resize via New-Object Size, [CmdletBinding()], perf false-positives silenced via PSGuard-disable/enable.

# Correction automatique « ⚡ Appliquer »Auto-fix "⚡ Apply"

Pour les règles auto-corrigeables, PS.Guard propose un bouton ⚡ Appliquer qui réécrit le code (alias → cmdlet complète, catch vide → Write-Error + throw, $Error[0]$_…). Les règles de sécurité exigent une correction manuelle (jamais auto-corrigées, par prudence).

For auto-fixable rules, PS.Guard offers a ⚡ Apply button that rewrites the code (alias → full cmdlet, empty catch → Write-Error + throw, $Error[0]$_…). Security rules require a manual fix (never auto-corrected, by design).

🔇
Faux positif sur un bloc statique ? Encadrez-le : # PSGuard-disable PSG-P02# PSGuard-enable PSG-P02.False positive on a static block? Wrap it: # PSGuard-disable PSG-P02# PSGuard-enable PSG-P02.

# Linter PF_* (temps réel)(real-time)

  • PF_ALIAS — alias détecté (ls, cat, rm…) → suggère la cmdlet complète.
  • PF_ALIAS — alias detected (ls, cat, rm…) → suggests the full cmdlet.
  • PF_UNDECLARED — variable utilisée sans assignation visible. Solution : $global: entre événements.
  • PF_UNDECLARED — variable used without a visible assignment. Fix: $global: across events.
  • PF_INVALID_PROP — propriété inexistante sur un contrôle (.Texte.Text, .MaxChars.MaxLength).
  • PF_INVALID_PROP — non-existent property on a control (.Texte.Text, .MaxChars.MaxLength).
ℹ️
Le linter analyse chaque événement isolément. Les contrôles du canvas et 50+ variables courantes sont en whitelist — une variable partagée entre deux événements reste signalée (utilisez $global:).The linter analyses each event in isolation. Canvas controls and 50+ common variables are whitelisted — a variable shared between two events is still flagged (use $global:).

⚠️ Top 10 des erreurs à éviterTop 10 mistakes to avoid

#ErreurMistakeSolutionFix
1Variable partagée sans $global:Shared var without $global:$global:maVar
2$form.Close()$script:form.Close()
3Traitement long dans Add_ClickLong task in Add_ClickStart-PF / Wait-PF / Sleep-PF
4Lire $script: dans -WorkReading $script: in -Work-With @{} + -Then
5Start-Sleep -Seconds 3Sleep-PF -Ms 3000
6Sleep-PF sans -EndSleep-PF without -Endtry/finally + Sleep-PF -Endtry/finally + Sleep-PF -End
7Pas de test $null après Pick-PF / Read-PFNo $null test after Pick-PF / Read-PFif ($null -ne $r) { … }
8MessageBox::Show("x")Alert-PF "x" / Show-PF "x"
9Catch videEmpty catchcatch { Write-Error $_; throw }
10Mauvais nom de contrôle (casse)Wrong control name (case)Copier le nom des PropriétésCopy the name from Properties
🎯
En résumé : respectez les scopes ($global: / $script:), passez par les fonctions *-PF (thread-safe), ne gelez jamais l'UI (async), et laissez PS.Guard + le linter valider le reste. En cas de doute, demandez à l'IA locale de l'application PulsiForms. In short: respect scopes ($global: / $script:), go through the *-PF functions (thread-safe), never freeze the UI (async), and let PS.Guard + the linter validate the rest. When in doubt, ask the PulsiForms local AI.