Commandes
Ce document détaille toutes les commandes prises en charge par Qwen Code, vous aidant à gérer efficacement les sessions, à personnaliser l’interface et à contrôler son comportement.
Les commandes de Qwen Code sont déclenchées via des préfixes spécifiques et se répartissent en trois catégories :
| Type de préfixe | Description de la fonction | Cas d’utilisation typique |
|---|---|---|
Commandes slash (/) | Contrôle de Qwen Code au niveau méta | Gestion des sessions, modification des paramètres, obtention d’aide |
Commandes at (@) | Injection rapide du contenu de fichiers locaux dans la conversation | Permettre à l’IA d’analyser des fichiers spécifiés ou du code dans des répertoires |
Commandes exclamation (!) | Interaction directe avec le Shell du système | Exécution de commandes système comme git status, ls, etc. |
1. Commandes slash (/)
Les commandes slash sont utilisées pour gérer les sessions, l’interface et le comportement de base de Qwen Code.
1.1 Gestion des sessions et des projets
Ces commandes vous aident à sauvegarder, restaurer et résumer l’avancement du travail.
| Commande | Description | Exemples d’utilisation |
|---|---|---|
/init | Analyser le répertoire actuel et créer le fichier de contexte initial | /init |
/summary | Générer un résumé du projet basé sur l’historique des conversations | /summary ou /summary docs/my-summary.md |
/compress | Remplacer l’historique du chat par un résumé pour économiser des Tokens | /compress ou /summarize |
/compress-fast | Compression rapide sans IA — supprime les anciennes sorties d’outils et les parties de réflexion | /compress-fast |
/resume | Reprendre une session de conversation précédente | /resume ou /continue |
/recap | Générer immédiatement un résumé d’une ligne de la session | /recap |
/restore | Rétablir les fichiers du projet au checkpoint avant l’exécution d’un appel d’outil | /restore (liste) ou /restore <ID> |
/delete | Supprimer une session précédente | /delete |
/branch | Forker la conversation actuelle dans une nouvelle session | /branch |
/fork | Lancer un agent en arrière-plan qui hérite de l’intégralité de la conversation | /fork <directive> |
/rewind | Rembobiner la conversation à un tour précédent | /rewind ou /rollback |
/export | Exporter l’historique de la session vers un fichier | /export html, /export md, /export json, /export jsonl |
/rename | Renommer ou taguer la session actuelle | /rename My Feature ou /tag |
/commit | Créer un commit git avec un message rédigé par l’IA | /commit ou /commit only stage the parser changes |
L’ouverture d’un export HTML charge le moteur de rendu et la feuille de style pour cette version exacte de Qwen Code depuis unpkg.com. Si la version n’a pas été publiée ou si l’un ou l’autre de ces éléments ne peut pas être atteint, le fichier affiche une erreur de chargement. Les exports Markdown, JSON et JSONL restent autonomes.
/summarize est un alias de /compress (il compresse l’historique du chat — une opération destructive). Pour générer plutôt un résumé de projet non destructif, utilisez /summary.
/summary accepte un argument optionnel [path] pour sauvegarder le résumé à un emplacement personnalisé dans la racine du projet. Sans argument, il sauvegarde dans .qwen/PROJECT_SUMMARY.md. Les résumés à chemin personnalisé ne sont pas détectés par le flux de bienvenue (ui.enableWelcomeBack), qui ne lit que l’emplacement par défaut .qwen/PROJECT_SUMMARY.md.
1.2 Contrôle de l’interface et de l’espace de travail
Commandes pour ajuster l’apparence de l’interface et l’environnement de travail.
| Commande | Description | Exemples d’utilisation |
|---|---|---|
/clear | Effacer l’historique des conversations et libérer le contexte | /clear, /reset, /new |
/context | Afficher la répartition de l’utilisation de la fenêtre de contexte | /context |
→ detail | Afficher la répartition de l’utilisation du contexte par élément | /context detail |
/history | Contrôler les préférences d’affichage et la visibilité de l’historique | /history collapse-on-resume, /history expand-on-resume, /history expand-now |
/diff | Ouvrir une visionneuse de diff interactive affichant les modifications non commitées et les diffs par tour. Utilisez ←/→ pour basculer entre le diff git actuel et les tours de conversation individuels, ↑/↓ pour parcourir les fichiers | /diff |
/log | Ouvrir une visionneuse de l’historique des commits pour le workspace (Web Shell uniquement) | /log |
/theme | Changer le thème visuel de Qwen Code | /theme |
/vim | Activer/Désactiver le mode d’édition Vim dans la zone de saisie | /vim |
/voice | Activer/Désactiver la saisie par dictée vocale | /voice, /voice hold, /voice tap, /voice off, /voice status |
/directory | Gérer l’espace de travail avec support multi-répertoires | /dir add ./src,./tests, /dir show |
/cd | Déplacer cette session vers un nouveau répertoire de travail | /cd ../other-project |
/editor | Ouvrir la boîte de dialogue pour sélectionner l’éditeur pris en charge | /editor |
/statusline | Ouvrir la boîte de dialogue interactive de préréglage de la ligne d’état | /statusline |
/statusline <text> | Générer une ligne d’état en mode commande via l’agent | /statusline show model and git branch |
/terminal-setup | Configurer les raccourcis clavier du terminal pour la saisie multiligne | /terminal-setup |
1.3 Paramètres de langue
Commandes spécifiquement dédiées au contrôle de la langue de l’interface et de la sortie.
| Commande | Description | Exemples d’utilisation |
|---|---|---|
/language | Afficher ou modifier les paramètres de langue | /language |
→ ui [language] | Définir la langue de l’interface utilisateur | /language ui zh-CN |
→ output [language] | Définir la langue de sortie du LLM | /language output Chinese |
- Langues de l’interface intégrées disponibles :
zh-CN(chinois simplifié),en-US(anglais),ru-RU(russe),de-DE(allemand),ja-JP(japonais),pt-BR(portugais - Brésil),fr-FR(français),ca-ES(catalan) - Exemples de langues de sortie :
Chinese,English,Japanese, etc.
1.4 Gestion des outils et des modèles
Commandes pour gérer les outils et les modèles d’IA.
| Commande | Description | Exemples d’utilisation |
|---|---|---|
/mcp | Lister les serveurs et outils MCP configurés | /mcp, /mcp desc, /mcp nodesc, /mcp schema |
/import-config | Importer des serveurs MCP depuis les configurations Claude | /import-config all, /import-config claude-code, /import-config claude-desktop --scope user|project |
/tools | Afficher la liste actuelle des outils disponibles | /tools, /tools desc |
/skills | Ouvrir le panneau Skills pour parcourir, rechercher, activer/désactiver et lancer des skills | /skills, /<skill-name> |
/learn | Créer une skill de projet réutilisable à partir d’un fichier, d’un répertoire, d’une URL, d’une vidéo ou d’un texte | /learn https://docs.example.com/api, /learn ./tutorial.mp4 focus on deployment |
/curator | Inspecter, épingler, archiver ou restaurer les auto-skills de projet inactives | /curator, /curator run --dry-run, /curator pin <directory>, /curator restore <directory> |
/plan | Passer en mode plan ou quitter le mode plan | /plan, /plan <task>, /plan exit |
/approval-mode | Changer le mode d’approbation des outils (session actuelle uniquement) | /approval-mode, /approval-mode auto-edit |
→ plan | Analyse uniquement, aucune exécution (revue sécurisée) | /approval-mode plan |
→ default | Exiger une approbation pour les modifications (usage quotidien) | /approval-mode default |
→ auto-edit | Approuver automatiquement les modifications (environnement de confiance) | /approval-mode auto-edit |
→ auto | Approbation évaluée par classifieur (autonome) | /approval-mode auto |
→ yolo | Tout approuver automatiquement (prototypage rapide) | /approval-mode yolo |
/peers | Examiner les messages entre pairs en attente ; gérer les contrôleurs de confiance | /peers, /peers accept <id>, /peers deny all, /peers controllers, /peers revoke <id> |
/model | Changer le modèle utilisé dans la session actuelle | /model, /model <model-id> (changer immédiatement) |
/model --fast | Définir un modèle plus léger pour les suggestions de prompts | /model --fast qwen3-coder-flash |
/model --voice | Définir le modèle utilisé pour la transcription vocale | /model --voice <model-id> |
/model --vision | Définir le modèle vision-bridge utilisé pour transcrire les images pour un modèle principal textuel | /model --vision <model-id> |
/model --compaction | Définir le modèle utilisé pour la compression du chat | /model --compaction <model-id>, /model --compaction clear |
/model --image | Définir un modèle capable de générer des images pour l’outil intégré de génération d’images | /model --image <model-id> |
/effort | Définir le niveau d’effort de raisonnement pour les modèles capables de réflexion | /effort (ouvre le sélecteur), /effort high (low/medium/high/xhigh/max ; mappé et limité par fournisseur) |
/output-style | Choisir le style de sortie qui façonne la rédaction des réponses | /output-style (ouvre le sélecteur), /output-style Concise, /output-style default (aucun style) |
/extensions | Gérer les extensions | /extensions list, /extensions manage |
→ list | Lister les extensions installées | /extensions list |
→ manage | Gérer les extensions installées (interactif) | /extensions manage |
→ explore | Ouvrir la page des extensions dans le navigateur | /extensions explore <Gemini|ClaudeCode> |
→ install | Installer une extension depuis un dépôt Git ou un chemin | /extensions install <repo-or-path> |
/memory | Ouvrir la boîte de dialogue du Gestionnaire de mémoire | /memory |
/remember | Sauvegarder une mémoire durable | /remember Prefer terse responses |
/forget | Supprimer les entrées correspondantes de la mémoire automatique | /forget <query> |
/dream | Exécuter manuellement la consolidation de la mémoire automatique | /dream |
/hooks | Gérer les hooks Qwen Code | /hooks, /hooks list |
/reload-plugins | Recharger les modifications des extensions (commandes, compétences, agents, workflows, hooks, serveurs MCP/LSP) depuis le disque | /reload-plugins |
/permissions | Gérer les règles de permission | /permissions |
/agents | Gérer les sous-agents | /agents manage, /agents create |
/arena | Gérer les sessions Arena | /arena start, /arena stop, /arena status, /arena select (alias choose) |
/goal | Définir un Objectif — continuer à travailler jusqu’à ce qu’un vérificateur le confirme (voir Objectifs) | /goal <objective>, /goal edit <objective>, /goal pause, /goal resume, /goal clear |
/tasks | Lister les tâches en arrière-plan | /tasks |
/workflows | Inspecter les exécutions de workflow ; mettre en pause/reprendre coopérativement une exécution en arrière-plan | /workflows, /workflows <runId>, /workflows p <runId> |
/lsp | Afficher le statut du serveur LSP | /lsp |
/trust | Gérer les paramètres de confiance des dossiers | /trust |
Installez uniquement des extensions (/extensions install) provenant de sources fiables. Les extensions peuvent inclure des serveurs MCP, des compétences et des commandes qui s’exécutent avec les mêmes autorisations que Qwen Code lui-même — elles peuvent accéder à vos fichiers, clés API et données de conversation. Elles peuvent également contenir des scripts de workflow, qui s’exécutent dans le bac à sable de workflow sans accès direct aux fichiers ou au shell, agissent via les sous-agents qu’ils lancent, et passent par l’approbation de l’outil Workflow. /extensions install ne demande pas de confirmation.
Les modes d’approbation auto-edit, auto et yolo contournent les invites d’approbation pour l’exécution des outils. En mode yolo, toutes les actions — y compris les commandes shell, les écritures de fichiers et les requêtes réseau — s’exécutent sans confirmation. N’utilisez ces modes que dans des environnements de confiance, sandboxés ou jetables.
/workflows, /lsp et /trust ne sont enregistrés que lorsque leur fonctionnalité est activée — respectivement via le paramètre tools.workflowsEnabled (portée utilisateur/système) ou la variable d’environnement QWEN_CODE_ENABLE_WORKFLOWS=1, le flag CLI --experimental-lsp et le paramètre security.folderTrust.enabled. Les valeurs workspace pour tools.workflowsEnabled sont ignorées. Lorsqu’ils sont désactivés, ils n’apparaîtront pas et signaleront une commande inconnue. De même, /dream et /forget ne sont enregistrés que lorsque l’auto-mémoire managée est disponible ; sans elle, ils n’apparaîtront pas.
Une compétence issue d’une extension installée est aussi une commande slash, et son nom porte son propriétaire : /rust:pdf, et non /pdf. La forme simple n’est pas un alias — si une autre compétence est nommée pdf, /pdf exécute cette compétence à la place. slashCommands.disabled contrôle une telle commande quelle que soit l’orthographe utilisée, afin qu’une entrée écrite avant que le nom ne porte le propriétaire reste effective. Voir Comment les compétences d’extension sont nommées.
1.5 Compétences intégrées
Ces commandes invoquent des compétences incluses qui fournissent des workflows spécialisés.
| Commande | Description | Exemples d’utilisation |
|---|---|---|
/review | Revue de code multi-agents (12 agents parallèles en effort élevé) | /review, /review 123, /review 123 --comment, /review --effort low |
/coordinate | Coordonner des workers en lecture seule et un writer optionnel dans un worktree | /coordinate investigate and fix the authentication regression |
/loop | Exécuter une invite selon un horaire récurrent | /loop 5m check the build |
/goal-draft | Transformer une intention floue en objectif /goal vérifiable | /goal-draft make the auth tests pass |
/autofix-pr | Surveiller une PR et corriger son CI, les retours de revue et les conflits | /autofix-pr 123, /autofix-pr 123 --once, /autofix-pr resume, /autofix-pr stop 123 |
/simplify | Examiner les modifications récentes et appliquer directement des nettoyages sûrs | /simplify, /simplify focus on duplication |
/qc-helper | Répondre aux questions sur l’utilisation et la configuration de Qwen Code | /qc-helper how do I configure MCP? |
Voir Revue de code pour la documentation complète de /review, et Correction automatique d’une Pull Request pour /autofix-pr.
1.6 Question annexe (/btw)
La commande /btw vous permet de poser des questions annexes rapides sans interrompre ni affecter le flux de la conversation principale.
| Commande | Description |
|---|---|
/btw <your question> | Poser une question rapide en marge |
?btw <your question> | Syntaxe alternative pour les questions marginales |
Fonctionnement :
- La question annexe est envoyée via un appel API séparé avec le contexte de conversation récent (jusqu’aux 20 derniers messages)
- La réponse s’affiche au-dessus du Composer — vous pouvez continuer à taper en attendant
- La conversation principale n’est pas bloquée — elle continue indépendamment
- La réponse à la question annexe ne fait pas partie de l’historique de la conversation principale
- Les réponses sont rendues avec le support complet du Markdown (blocs de code, listes, tableaux, etc.)
Raccourcis clavier (Mode interactif) :
| Raccourci | Action |
|---|---|
Escape | Annuler (pendant le chargement) ou fermer (une fois terminé) |
Space ou Enter | Fermer la réponse (lorsque l’input est vide) |
Ctrl+C ou Ctrl+D | Annuler une question annexe en cours |
Exemple :
(While the main conversation is about refactoring code)
> /btw What's the difference between let and var in JavaScript?
╭──────────────────────────────────────────╮
│ /btw What's the difference between let │
│ and var in JavaScript? │
│ │
│ + Answering... │
│ Press Escape, Ctrl+C, or Ctrl+D to cancel│
╰──────────────────────────────────────────╯
> (Composer remains active — keep typing)
(After the answer arrives)
╭──────────────────────────────────────────╮
│ /btw What's the difference between let │
│ and var in JavaScript? │
│ │
│ `let` is block-scoped, while `var` is │
│ function-scoped. `let` was introduced │
│ in ES6 and doesn't hoist the same way. │
│ │
│ Press Space, Enter, or Escape to dismiss │
╰──────────────────────────────────────────╯
> (Composer still active)Modes d’exécution supportés :
| Mode | Comportement |
|---|---|
| Interactive | Affiche au-dessus du Composer avec le rendu Markdown |
| Non-interactive | Retourne le résultat texte : btw> question\nanswer |
| ACP (Agent Protocol) | Retourne un générateur asynchrone stream_messages |
Utilisez /btw lorsque vous avez besoin d’une réponse rapide sans perdre le fil de votre tâche principale. C’est particulièrement utile pour clarifier des concepts, vérifier des faits ou obtenir des explications rapides tout en restant concentré sur votre workflow principal.
1.7 Second avis (/advisor)
La commande /advisor exécute une revue indépendante et en lecture seule de la conversation jusqu’à ce point et renvoie un second avis structuré — sans effectuer la tâche ni interrompre la conversation principale.
| Commande | Description |
|---|---|
/advisor | Revoir la conversation ci-dessus |
/advisor <focus> | Centrer la revue sur un sujet précis |
Fonctionnement :
- La revue est envoyée via un appel API séparé et en tour unique avec le contexte de conversation récent (jusqu’aux 40 derniers messages)
- Le modèle relecteur ne peut pas exécuter d’outils — les outils sont retirés au niveau de la requête (le même mécanisme que
/btw), donc la revue n’écrit jamais de code ni n’exécute de commandes ; chaque affirmation doit être ancrée dans la transcription visible - La conversation principale n’est pas interrompue ; la revue vous est montrée uniquement
- La revue est rendue sous forme de bloc markdown encadré avec quatre sections fixes — Verdict, Risques, Preuves manquantes et Recommandation — sous un en-tête
/advisor · <model>qui nomme le modèle relecteur résolu - Contrairement à
/btw, qui est fire-and-forget et laisse la session utilisable,/advisorbloque la saisie jusqu’au retour de la revue ; sur une fenêtre de contexte complète avec un relecteur puissant, cela peut prendre des dizaines de secondes - Par défaut, le modèle principal est utilisé ; définissez
advisorModelpour acheminer la revue vers un modèle différent (généralement plus puissant) — la transcription récente est envoyée à ce modèle même s’il utilise un autre fournisseur
Exemple :
> /advisor is my fix for the null check actually correct?
Consulting advisor...
╭──────────────────────────────────────────────────────╮
│ /advisor · qwen3-max │
│ │
│ Verdict │
│ The approach is sound, but the edge case at line 42 │
│ is unverified. │
│ │
│ Risks │
│ - The fix assumes the config is always loaded; a │
│ startup race could leave it null. │
│ │
│ Missing evidence │
│ - No test exercises the null-config path in the │
│ visible transcript. │
│ │
│ Recommendation │
│ Add a focused unit test for the null-config branch │
│ before merging. │
╰──────────────────────────────────────────────────────╯La revue s’affiche dans une boîte encadrée dont l’en-tête nomme le modèle relecteur résolu. Un advisorModel inconnu n’est pas validé au préalable — si le fournisseur le rejette, /advisor signale l’échec, vérifiez donc le nom du modèle ; seuls les sélecteurs d’alias non résolus (par ex. fast sans modèle rapide configuré) reviennent au modèle principal. Les requêtes Advisor n’utilisent pas les fallbacks de modèle configurés.
Modes d’exécution supportés :
| Mode | Comportement |
|---|---|
| Interactive | Rend la revue en quatre sections dans la conversation |
| ACP (Agent Protocol) | Renvoie la revue en tant que résultat de message |
Utilisez /advisor pour un second avis avant de vous engager dans une direction — c’est particulièrement utile pour détecter des hypothèses erronées, des affirmations non vérifiées ou des prochaines étapes risquées. Configurez advisorModel pour obtenir la revue d’un modèle différent de celui qui pilote la conversation principale.
advisorModel est défini dans les paramètres uniquement ; contrairement à fastModel et visionModel, il n’a pas encore de pendant via un flag /model.
1.8 Récapitulatif de session (/recap)
La commande /recap génère un court résumé « où vous en étiez » de la session actuelle, afin que vous puissiez reprendre une ancienne conversation sans faire défiler des pages d’historique.
| Commande | Description |
|---|---|
/recap | Génère et affiche un récapitulatif de session sur une ligne |
Fonctionnement :
- Utilise le modèle rapide configuré (paramètre
fastModel) lorsqu’il est disponible, sinon utilise le modèle principal de la session. Un petit modèle peu coûteux suffit pour un récapitulatif. - La conversation récente (jusqu’à 30 messages, texte uniquement — les appels et réponses aux outils sont filtrés) est envoyée au modèle avec une invite système concise.
- Le récapitulatif est affiché dans une couleur atténuée avec un préfixe
❯afin de se distinguer des vraies réponses de l’assistant. - Refuse avec une erreur en ligne si un tour du modèle est en cours ou si une autre commande est en traitement. S’il n’y a pas de conversation utilisable, ou si la génération sous-jacente échoue,
/recapaffiche un court message d’information au lieu d’un récapitulatif — la commande manuelle répond toujours par quelque chose.
Déclenchement automatique lors du retour après une absence :
Si le terminal est flou pendant plus de 5 minutes et qu’il redevient actif, un récapitulatif est généré et affiché automatiquement (uniquement lorsqu’aucune réponse du modèle n’est en cours ; sinon il attend la fin du tour actuel puis s’exécute). Contrairement à la commande manuelle, le déclencheur automatique est totalement silencieux en cas d’échec : si la génération échoue ou s’il n’y a rien à résumer, aucun message n’est ajouté à l’historique. Contrôlé par le paramètre general.showSessionRecap (par défaut : false) ; la commande manuelle /recap fonctionne toujours indépendamment de ce paramètre.
Exemple :
> /recap
❯ Refactoring loopDetectionService.ts to address long-session OOM caused by
unbounded streamContentHistory and contentStats. The next step is to
implement option B (LRU sliding window with FNV-1a) pending confirmation.Configurez un modèle rapide via /model --fast <model> (par ex. qwen3-coder-flash) pour rendre /recap rapide et peu coûteux. Définissez general.showSessionRecap sur true pour activer le déclencheur automatique ; la commande manuelle /recap fonctionne toujours indépendamment de ce paramètre.
1.9 Visionneuse de diff (/diff)
La commande /diff ouvre une visionneuse de diff interactive affichant les modifications non commitées et les diffs par tour. Utilisez ←/→ pour basculer entre le git diff actuel et les tours de conversation individuels, ↑/↓ pour parcourir les fichiers, et Enter pour voir les diffs inline.
Fonctionnement :
En mode interactif, /diff ouvre une boîte de dialogue avec un sélecteur de source en haut :
- Current — working tree vs HEAD (
git diff HEAD). Affiche toutes les modifications non commitées, y compris les fichiers stagés, non stagés et non suivis. - T1, T2, T3, … — diffs par tour, un onglet par tour de modèle qui a modifié des fichiers. Les tours les plus récents apparaissent en premier. Chaque onglet affiche un aperçu du prompt original pour le contexte.
La liste de fichiers affiche les statistiques par fichier (lignes ajoutées/supprimées) avec des tags pour les états spéciaux (new, deleted, untracked, binary, truncated, oversized). Appuyez sur Enter sur un fichier pour voir son diff inline avec les hunks colorés syntaxiquement.
Les diffs par tour nécessitent que le checkpointing de fichiers soit activé (activé par défaut en mode interactif). Lorsque le checkpointing de fichiers est désactivé, seule la source “Current” est disponible.
Raccourcis clavier :
| Touche | Action |
|---|---|
← / → | Basculer entre les sources (Current / T1 / T2…) |
↑ / ↓ | Naviguer dans la liste de fichiers |
j / k | Naviguer dans la liste de fichiers (style vim) |
| Enter | Voir le diff inline pour le fichier sélectionné |
← / Esc | Retourner à la liste de fichiers depuis la vue diff inline |
| Esc | Fermer la boîte de dialogue |
Exemple :
┌ /diff · Turn 3 "refactor the auth middleware" ──── 3 files +45 -12 ┐
│ │
│ ◀ Current · T3 · T2 · T1 ▶ │
│ │
│ › src/utils/parser.ts +30 -8 │
│ src/utils/parser.test.ts +12 -2 │
│ README.md +3 -2 │
│ │
│ ←/→ source · ↑/↓ file · Enter view · Esc close │
└─────────────────────────────────────────────────────────────────────┘Mode non interactif :
En mode headless (--prompt) ou dans des contextes non interactifs, /diff affiche un résumé en texte brut du working tree vs HEAD. La navigation par tour n’est pas disponible.
3 files changed, +45 / -12
+30 -8 src/utils/parser.ts
+12 -2 src/utils/parser.test.ts
+3 -2 README.mdWeb Shell : Dans l’interface Web Shell (qwen serve), /diff ouvre une boîte de dialogue graphique de diff. Une barre d’onglets en haut vous permet de basculer entre la vue Changes et la vue History (/log).
Visualiseur d’historique (/log) — Web Shell uniquement
La commande /log ouvre un navigateur d’historique de commits pour le workspace actuel. Elle est disponible uniquement dans l’interface Web Shell ; le CLI/TUI ne dispose pas de cette commande.
Fonctionnement :
/log ouvre une boîte de dialogue listant les commits par ordre chronologique inverse (les plus récents en premier). Chaque ligne affiche :
- SHA court (monospace, avec un bouton de copie pour le SHA complet)
- Sujet du commit (une seule ligne)
- Nom de l’auteur et temps relatif (par ex. “2h ago”)
- Étiquettes de référence branche/tag, lorsque présentes
- Une icône de merge (⎇) pour les commits de merge
Cliquez sur une ligne de commit pour déplier ses détails à la demande :
- Corps complet du message de commit
- Statistiques de modification des fichiers (fichiers modifiés, lignes ajoutées/supprimées, détail par fichier)
Utilisez Load more en bas pour récupérer la page suivante de commits (50 par page).
Exemple :
┌─ History ──────────────────────────── 50 commits ─ ✕ ┐
│ │
│ a1b2c3d feat(cli): add --json flag 2h ago │
│ wenshao │
│ │
│ e4f5g6h fix(core): handle null config 5h ago │
│ dev · main v1.2.0 │
│ │
│ ▼ 789abcd refactor: simplify parser 1d ago │
│ ┌─────────────────────────────────────────────┐ │
│ │ Broke the monolithic parse() into smaller │ │
│ │ functions for readability. │ │
│ │ │ │
│ │ 3 files · +45 −12 │ │
│ │ +30 −8 src/parser.ts │ │
│ │ +10 −2 src/utils.ts │ │
│ │ +5 −2 test/parser.test.ts │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ [ Load more ] │
└───────────────────────────────────────────────────────┘/log nécessite un workspace de dépôt git. Si le workspace n’est pas un dépôt git ou n’a pas de commits, la boîte de dialogue affiche un message placeholder.
1.10 Informations, paramètres et aide
Commandes pour obtenir des informations et configurer le système.
| Commande | Description | Exemples d’utilisation |
|---|---|---|
/help | Affiche l’aide pour les commandes disponibles | /help ou /? |
/status | Affiche les informations de version | /status ou /about |
/status paths | Affiche les chemins des fichiers et des logs de la session en cours | /status paths |
/stats | Ouvre le tableau de bord interactif des statistiques d’utilisation (onglets Session, Activity et Efficiency) | /stats ou /usage |
/stats model | Affiche la répartition des tokens par modèle et le coût estimé | /stats model |
/stats tools | Affiche le nombre d’appels par outil | /stats tools |
/stats skills | Affiche le nombre d’appels par skill pour la session live en cours (live uniquement ; exclut l’activité quotidienne/mensuelle inter-sessions) | /stats skills |
/stats daily | Affiche les statistiques d’utilisation des tokens par jour | /stats daily (alias day), /stats day [YYYY-MM-DD] |
/stats monthly | Affiche les statistiques d’utilisation des tokens par mois | /stats monthly (alias month), /stats month [YYYY-MM] |
/stats export | Exporte les statistiques d’utilisation en CSV ou JSON | /stats export <daily|monthly> [date|month] [--format csv|json] [--output path] |
/settings | Ouvre l’éditeur de paramètres | /settings |
/config | Obtient ou définit n’importe quel paramètre par sa clé dot-path (écrit dans les paramètres utilisateur) | /config (liste tout), /config <key>, /config <key>=<value> |
/auth | Change la méthode d’authentification | /auth, /connect, /login |
/logout | Se déconnecter du compte Qwen Subscription actif (disponible avec la connexion Qwen Subscription) | /logout |
/upgrade | Ouvrir les plans d’abonnement Qwen (disponibles avec la connexion Qwen Subscription) | /upgrade |
/doctor | Exécute les diagnostics d’installation et d’environnement | /doctor, /doctor memory |
→ memory | Affiche les diagnostics de mémoire du processus en cours | /doctor memory [--json] [--sample] [--snapshot] |
→ cpu-profile | Enregistre un profil CPU pour l’analyse dans Chrome DevTools | /doctor cpu-profile [--duration <seconds>] |
→ rollback | Restaure le binaire CLI standalone à la version précédente (installations standalone uniquement ; pour l’historique de conversation utilisez /rewind) | /doctor rollback |
/docs | Ouvre la documentation complète de Qwen Code dans le navigateur | /docs |
/ide | Gère l’intégration IDE | /ide status, /ide install, /ide enable, /ide disable |
/insight | Génère des insights de programmation à partir de l’historique du chat | /insight |
/setup-github | Configure GitHub Actions | /setup-github |
/bug | Soumet un problème concernant Qwen Code | /bug Button click unresponsive |
/copy | Copie dans le presse-papiers : réponse (N-ième avant la fin), code (par lang), LaTeX ou Mermaid | /copy, /copy 2, /copy python, /copy latex, /copy mermaid |
/quit | Quitte Qwen Code immédiatement | /quit ou /exit |
/doctor memory --snapshot écrit un instantané du tas V8 (heap snapshot) qui peut contenir des prompts, des contenus de fichiers, des clés API et des résultats d’outils de la session en cours. Vérifiez le fichier avant de le partager.
/config lit et écrit des paramètres individuels via une clé dot-path (par ex. general.vimMode), en complément de l’éditeur interactif /settings. Exécuter /config sans argument (ou avec --help) liste toutes les clés configurables avec leur type et leur valeur actuelle. /config <key> affiche la valeur actuelle — sauf pour les clés booléennes, où cela bascule la valeur. /config <key>=<value> définit la valeur. Les modifications sont écrites dans les paramètres utilisateur (~/.qwen/settings.json). Seuls les paramètres de type boolean, string, number et enum peuvent être modifiés de cette façon — les paramètres array et object doivent être édités directement dans settings.json. Les valeurs sensibles (clés API, tokens, URLs de base) sont masquées dans la sortie, et la définition de tools.approvalMode à yolo est bloquée.
1.11 Raccourcis courants
| Raccourci | Fonction | Note |
|---|---|---|
Ctrl/cmd+L | Effacer l’écran | Efface uniquement l’écran visible (ne réinitialise pas la session comme /clear) |
Ctrl/cmd+T | Basculer la description de l’outil | Gestion des outils MCP |
Ctrl/cmd+C×2 | Confirmation de sortie | Mécanisme de sortie sécurisé |
Ctrl/cmd+Z | Annuler la saisie | Édition de texte |
Ctrl/cmd+Shift+Z | Rétablir la saisie | Édition de texte |
1.12 Commandes d’authentification
Utilisez /auth dans une session Qwen Code pour configurer l’authentification. Utilisez /doctor pour inspecter l’état actuel de l’authentification et de l’environnement.
| Commande | Description |
|---|---|
/auth | Configurer l’authentification de manière interactive (alias : /connect, /login) |
/doctor | Afficher les vérifications d’authentification et d’environnement |
La commande CLI autonome qwen auth a été supprimée. Les invocations héritées telles que qwen auth status affichent un avis de suppression avec des instructions de migration. Consultez la page Authentication pour plus de détails.
2. Commandes @ (Introduction de fichiers)
Les commandes @ sont utilisées pour ajouter rapidement le contenu d’un fichier ou d’un répertoire local à la conversation.
| Format de la commande | Description | Exemples |
|---|---|---|
@<file path> | Injecter le contenu d’un fichier spécifié | @src/main.py Please explain this code |
@<directory path> | Lire récursivement tous les fichiers texte dans un répertoire | @docs/ Summarize content of this document |
@ autonome | Utilisé lors de la discussion sur le symbole @ lui-même | @ What is this symbol used for in programming? |
Note : Les espaces dans les chemins doivent être échappés avec un antislash (par ex. @My\ Documents/file.txt)
Dans l’invite interactive, la complétion @ prend en charge les noms de fichiers Unicode, y compris les emojis. Les emojis ailleurs dans l’invite ne modifient pas le chemin de fichier utilisé pour la complétion.
3. Commandes avec point d’exclamation (!) - Exécution de commandes Shell
Les commandes avec point d’exclamation vous permettent d’exécuter des commandes système directement dans Qwen Code.
| Format de la commande | Description | Exemples |
|---|---|---|
!<shell command> | Exécuter une commande dans un sous-Shell | !ls -la, !git status |
! seul | Basculer en mode Shell, toute saisie est exécutée directement comme commande Shell | !(entrée) → Saisir la commande → !(sortie) |
Variables d’environnement : Les commandes exécutées via ! définiront la variable d’environnement QWEN_CODE=1.
4. Commandes personnalisées
Enregistrez les prompts fréquemment utilisés comme commandes raccourcies pour améliorer l’efficacité du travail et garantir la cohérence.
Les commandes personnalisées utilisent désormais le format Markdown avec un frontmatter YAML optionnel. Le format TOML est obsolète mais reste pris en charge pour la rétrocompatibilité. Lorsque des fichiers TOML sont détectés, une invite de migration automatique sera affichée.
Aperçu rapide
| Fonction | Description | Avantages | Priorité | Scénarios applicables |
|---|---|---|---|---|
| Espace de noms (Namespace) | Un sous-répertoire crée des commandes nommées avec des deux-points | Meilleure organisation des commandes | ||
| Commandes globales | ~/.qwen/commands/ | Disponibles dans tous les projets | Basse | Commandes personnelles fréquemment utilisées, utilisation multi-projets |
| Commandes de projet | <project root directory>/.qwen/commands/ | Spécifiques au projet, versionnables | Élevée | Partage en équipe, commandes spécifiques au projet |
Règles de priorité : Commandes de projet > Commandes utilisateur (la commande de projet est utilisée en cas de noms identiques)
Règles de nommage des commandes
Tableau de correspondance entre le chemin du fichier et le nom de la commande
| Emplacement du fichier | Commande générée | Exemple d’appel |
|---|---|---|
~/.qwen/commands/test.md | /test | /test Parameter |
<project>/.qwen/commands/git/commit.md | /git:commit | /git:commit Message |
Règles de nommage : Le séparateur de chemin (/ ou \) est converti en deux-points (:)
Spécification du format de fichier Markdown (Recommandé)
Les commandes personnalisées utilisent des fichiers Markdown avec un frontmatter YAML facultatif :
---
description: Optional description (displayed in /help)
---
Your prompt content here.
Use {{args}} for parameter injection.| Champ | Requis | Description | Exemple |
|---|---|---|---|
description | Facultatif | Description de la commande (affichée dans /help) | description: Code analysis tool |
| Corps du prompt | Requis | Contenu du prompt envoyé au modèle | Tout contenu Markdown après le frontmatter |
Format de fichier TOML (Obsolète)
Obsolète : Le format TOML est encore pris en charge mais sera supprimé dans une future version. Veuillez migrer vers le format Markdown.
| Champ | Requis | Description | Exemple |
|---|---|---|---|
prompt | Requis | Contenu du prompt envoyé au modèle | prompt = "Please analyze code: {{args}}" |
description | Facultatif | Description de la commande (affichée dans /help) | description = "Code analysis tool" |
Mécanisme de traitement des paramètres
| Méthode de traitement | Syntaxe | Scénarios applicables | Fonctionnalités de sécurité |
|---|---|---|---|
| Injection contextuelle | {{args}} | Besoin d’un contrôle précis des paramètres | Échappement Shell automatique |
| Traitement par défaut des paramètres | Aucune marque spéciale | Commandes simples, ajout de paramètres | Ajout tel quel |
| Injection de commande Shell | !{command} | Besoin de contenu dynamique | Confirmation d’exécution requise avant |
1. Injection contextuelle ({{args}})
| Scénario | Configuration TOML | Méthode d’appel | Effet réel |
|---|---|---|---|
| Injection brute | prompt = "Fix: {{args}}" | /fix "Button issue" | Fix: "Button issue" |
| Dans une commande Shell | prompt = "Search: !{grep {{args}} .}" | /search "hello" | Exécute grep "hello" . |
2. Traitement des paramètres par défaut
| Situation d’entrée | Méthode de traitement | Exemple |
|---|---|---|
| A des paramètres | Ajouter à la fin du prompt (séparés par deux sauts de ligne) | /cmd parameter → Prompt original + paramètre |
| Sans paramètres | Envoi du prompt tel quel | /cmd → Prompt original |
🚀 Injection de contenu dynamique
| Type d’injection | Syntaxe | Ordre de traitement | Objectif |
|---|---|---|---|
| Contenu de fichier | @{file path} | Traité en premier | Injecter des fichiers de référence statiques |
| Commandes Shell | !{command} | Traité au milieu | Injecter des résultats d’exécution dynamiques |
| Remplacement de paramètres | {{args}} | Traité en dernier | Injecter des paramètres utilisateur |
3. Exécution de commandes Shell (!{...})
| Opération | Interaction utilisateur |
|---|---|
| 1. Analyser la commande et les paramètres | - |
| 2. Échappement Shell automatique | - |
| 3. Afficher la boîte de dialogue de confirmation | ✅ Confirmation utilisateur |
| 4. Exécuter la commande | - |
| 5. Injecter la sortie dans l’invite | - |
Exemple : Génération de message de commit Git
---
description: Generate Commit message based on staged changes
---
Please generate a Commit message based on the following diff:
```diff
!{git diff --staged}
```4. Injection de contenu de fichier (@{...})
| Type de fichier | Statut de prise en charge | Méthode de traitement |
|---|---|---|
| Fichiers texte | ✅ Prise en charge complète | Injection directe du contenu |
| Images/PDF | ✅ Prise en charge multimodale | Encodage et injection |
| Fichiers binaires | ⚠️ Prise en charge limitée | Peut être ignoré ou tronqué |
| Répertoire | ✅ Injection récursive | Suit les règles .gitignore |
Exemple : Commande de revue de code
---
description: Code review based on best practices
---
Review {{args}}, reference standards:
@{docs/code-standards.md}Exemple pratique de création
Tableau des étapes de création de la commande « Refactorisation en fonction pure »
| Opération | Commande/Code |
|---|---|
| 1. Créer la structure de répertoires | mkdir -p ~/.qwen/commands/refactor |
| 2. Créer le fichier de commande | touch ~/.qwen/commands/refactor/pure.md |
| 3. Éditer le contenu de la commande | Se référer au code complet ci-dessous. |
| 4. Tester la commande | @file.js → /refactor:pure |
---
description: Refactor code to pure function
---
Please analyze code in current context, refactor to pure function.
Requirements:
1. Provide refactored code
2. Explain key changes and pure function characteristic implementation
3. Maintain function unchangedRésumé des bonnes pratiques pour les commandes personnalisées
Tableau des recommandations de conception de commandes
| Points de pratique | Approche recommandée | À éviter |
|---|---|---|
| Nommage des commandes | Utiliser des espaces de noms pour l’organisation | Éviter les noms trop génériques |
| Traitement des paramètres | Utiliser clairement {{args}} | S’appuyer sur l’ajout par défaut (facile à confondre) |
| Gestion des erreurs | Exploiter la sortie d’erreur Shell | Ignorer l’échec d’exécution |
| Organisation des fichiers | Organiser par fonction dans des répertoires | Toutes les commandes dans le répertoire racine |
| Champ Description | Toujours fournir une description claire | Se fier à la description générée automatiquement |
Tableau de rappel des fonctionnalités de sécurité
| Mécanisme de sécurité | Effet de protection | Opération utilisateur |
|---|---|---|
| Échappement Shell | Empêche l’injection de commande | Traitement automatique |
| Confirmation d’exécution | Évite l’exécution accidentelle | Confirmation par dialogue |
| Rapport d’erreur | Aide au diagnostic des problèmes | Consulter les informations d’erreur |
5. Sous-commandes CLI
Ces commandes sont exécutées depuis le shell sous la forme qwen <subcommand> avant de démarrer une session interactive.
Gestion des sessions
| Commande | Description | Exemples d’utilisation |
|---|---|---|
qwen sessions list | Liste les sessions de conversation récentes | qwen sessions list, qwen sessions list --json --limit 50 |
qwen sessions ps | Liste les sessions interactives en cours d’exécution | qwen sessions ps, qwen sessions ps --json |
qwen sessions controllers | Gérer les tokens de contrôleurs fiables | qwen sessions controllers add --label <name>, qwen sessions controllers list |
qwen sessions list
Liste vos sessions Qwen Code récentes avec leurs métadonnées.
Options :
| Option | Type | Défaut | Description |
|---|---|---|---|
--json | boolean | false | Sortie au format JSON Lines (un objet JSON par ligne) |
--limit | number | 20 | Nombre maximum de sessions à afficher |
Sortie lisible par l’homme (par défaut) :
Un tableau avec les colonnes : SESSION ID, STARTED (horodatage UTC), TITLE, BRANCH, PROMPT.
Sortie JSON (--json) :
Génère des JSON Lines sur stdout. Chaque ligne est un objet JSON contenant les champs suivants :
sessionId, startTime, mtime, prompt, gitBranch, customTitle, titleSource, filePath, cwdL’indication « has more sessions » est émise via stderr afin que le piping vers jq reste sûr.
Exemples :
# Show last 20 sessions (default)
qwen sessions list
# Show last 50 sessions
qwen sessions list --limit 50
# Output as JSON for scripting
qwen sessions list --json | jq .qwen sessions ps
Liste les enregistrements de sessions Qwen Code visibles sur cette machine. sessions list parcourt les transcriptions sauvegardées (« sur quoi ai-je travaillé »). Cette commande affiche à la fois le registre des processus actifs et les enregistrements Agent View marqués managed. Les enregistrements laissés par une session tuée sont nettoyés du registre dès qu’ils sont trouvés. Un enregistrement géré est une tenue de livres persistante, non une preuve que son worker est encore vivant. Une exécution unique qwen -p ne s’enregistre jamais et n’est pas affichée.
Options :
| Option | Type | Défaut | Description |
|---|---|---|---|
--json | booléen | false | Sortie au format JSON Lines (un objet JSON par ligne) |
Sortie lisible par l’homme (par défaut) :
Un tableau avec les colonnes : NAME, KIND, PID, AGE, DIRECTORY.
KIND indique ce qui a enregistré la session — tui pour quelqu’un devant un terminal, external pour un programme qui n’est pas du tout une session Qwen Code (une interface vocale, un relais), et headless ou serve pour une session pilotée par un autre programme. Plusieurs lignes serve ou headless peuvent partager un même PID : un enfant qwen --acp héberge toutes ses sessions dans un seul processus — serve lorsque le démon l’a lancé, headless lorsqu’un client le pilote directement — et chacun d’eux s’enregistre séparément lorsque la messagerie entre pairs est active. Une session hébergée ne s’enregistre pas ici si son propre environnement la place en mode nu ou sécurisé. Le --bare d’un démon n’atteint pas les sessions qu’il héberge (QWEN_CODE_SIMPLE est retiré de l’environnement de l’enfant) ; un QWEN_CODE_SAFE_MODE hérité atteint ces sessions, les gardant hors de cette liste. C’est une auto-déclaration, comme NAME et DIRECTORY : chaque champ ici a été écrit par le processus qu’il décrit, et rien de ce qu’une session est autorisée à faire n’en dépend. Un enregistrement Agent View marqué managed utilise managed pour KIND et - pour PID et AGE. Il reste une ligne distincte lorsque la même session possède également un enregistrement actif dans le registre. Voir Protocole inter-sessions pour le format d’enregistrement et pour savoir comment enregistrer votre propre programme.
Sortie JSON (--json) :
Affiche des lignes JSON sur stdout avec les enregistrements gérés en premier. Les enregistrements du registre conservent leur structure existante :
schemaVersion, pid, procStart, pidNs, sessionId, cwd, name, startedAt,
qwenVersion, kind, ipcPath (when peer messaging is available)Un enregistrement géré contient uniquement des données issues de sources fiables :
sessionId, cwd, managed: trueRien d’autre n’est écrit sur stdout — une liste vide n’affiche rien du tout — donc qwen sessions ps --json | jq . est sûr à utiliser dans des scripts. Si le magasin du superviseur ne peut pas être lu, les enregistrements du registre s’affichent quand même et la raison est écrite sur stderr.
La sortie JSON est des données brutes : les valeurs des champs sont émises exactement telles qu’enregistrées, sans assainissement pour le terminal. Traitez-les comme des données, et assainissez-les avant de les afficher dans un terminal.
Exemples :
# Show the other live sessions
qwen sessions ps
# Which directories have a visible session record?
# Note: `jq -r` renders the raw recorded value in your terminal (see the
# raw-data note above); pipe through a sanitizer if the path is untrusted.
qwen sessions ps --json | jq -r .cwd6. Envoyer des messages à une autre session active
Deux sessions interactives sur la même machine peuvent s’envoyer des messages mutuellement. La fonctionnalité est activée par défaut, mais --bare et --safe-mode la désactivent indépendamment du paramètre. Avec une boîte de réception à l’écoute, une session est découvrable par les autres sessions du même utilisateur sur la machine, et ce qu’elles lui envoient passe par les règles de revue ci-dessous avant que son modèle n’en voie quoi que ce soit. Pour désactiver la découverte et la messagerie entre pairs, désactivez-la dans settings.json et redémarrez :
{ "agents": { "crossSessionMessaging": false } }Une session interactive avec la messagerie entre pairs désactivée peut toujours apparaître dans qwen sessions ps, mais n’a pas de ipcPath et n’est pas un pair accessible dans list_agents. L’interface OpenTUI ne lie pas non plus de boîte de réception entre pairs ; activer le paramètre seul ne la rend pas capable de recevoir des messages.
Avec la messagerie active, le modèle d’une session peut découvrir les autres avec list_agents — chacun apparaît sous sessions avec le name que qwen sessions ps --json enregistre (la vue tableau peut tronquer les noms longs) — et adresser l’un d’eux avec send_message en utilisant ce nom comme to. Lorsque deux sessions partagent un nom, list_agents affiche chacune avec un court [ref] et l’envoi doit l’inclure (name [ref]) ; un nom simple qui pourrait désigner l’une ou l’autre est refusé plutôt que deviné. list_agents rapporte également le nom propre de la session sous self, et to: "*" signifie toujours « mes coéquipiers Agent Team » et n’atteint jamais les autres sessions.
Un message arrive dans l’autre session marqué comme provenant d’une autre session, et non de son utilisateur, et ne porte aucune de vos autorisations là-bas : la session réceptrice agit dessus uniquement selon ses propres paramètres d’autorisation. Son utilisateur peut choisir ce qui arrive aux messages entrants avec agents.crossSessionInbound (accept, hold ou refuse). Lorsqu’il n’est pas défini, un message n’est livré que si les deux sessions sont dans la même classe de revue : les deux examinent encore chaque action (mode par défaut ou plan), ou les deux sont dans un mode qui applique certaines actions sans revue par action (auto-edit, auto ou yolo). Un message provenant d’une session de l’autre classe, ou d’un expéditeur qui n’indique pas sa classe, est mis en attente pour revue — dans les deux sens. Une session qui examine chaque action met en attente un message provenant d’une qui ne le fait pas, car ce message a été écrit par un modèle que personne ne surveillait, et les invites par action protègent les actions, pas ce vers quoi la session est entraînée. Les messages en attente sont listés et libérés avec /peers dans la session réceptrice, et un message retenu uniquement parce que les modes différaient est libéré automatiquement dès qu’ils s’accordent.
Un dépôt peut rendre les sessions ouvertes dedans plus prudentes, jamais moins : un espace de travail .qwen/settings.json peut définir agents.crossSessionInbound sur hold ou refuse, ou agents.crossSessionMessaging sur false, et cette valeur prime sur une valeur plus permissive dans vos paramètres utilisateur. Une valeur d’espace de travail qui assouplirait une valeur définie par l’opérateur (accept, ou true pour le commutateur lorsqu’une portée utilisateur ou système l’a défini sur false) est ignorée avec un avertissement ; un true d’espace de travail où rien d’autre n’a défini le commutateur se contente de répéter la valeur par défaut et est supprimé silencieusement. Une valeur que la CLI ne reconnaît pas met tous les messages en attente chaque fois qu’elle est la valeur effective. Les paramètres système prévalent sur tout cela, comme pour tous les paramètres.
Une mise en attente n’attend pas indéfiniment. Un message sur lequel personne ne décide expire après agents.crossSessionHeldExpiry — 1m, 5m, 10m ou never, cinq minutes par défaut — et la session émettrice est informée qu’aucune décision n’est venue. Raccourcir le paramètre s’applique aux messages déjà en attente.
Si la session ne peut pas lier sa boîte de réception — le répertoire d’exécution est manquant, appartient à un autre utilisateur, ou est en lecture seule, comme cela peut être le cas dans un conteneur — elle essaie d’abord un répertoire privé sous le répertoire temporaire, et ne démarre sans boîte de réception que si cela échoue aussi. Dans ce cas, la session le signale au démarrage, et /peers répète la raison et ce qu’il faut changer (généralement XDG_RUNTIME_DIR ou TMPDIR).
Deux sessions peuvent aussi résoudre la même adresse de boîte de réception, car l’adresse est indexée par identifiant de processus et les identifiants de processus se répètent entre les conteneurs partageant un répertoire d’exécution. La session démarrant en second prend une adresse voisine au lieu de prendre celle en cours d’utilisation, afin que ni l’une ni l’autre ne devienne inaccessible. Les pairs ne sont pas affectés : ils lisent l’adresse d’une session depuis le registre des sessions plutôt que de la dériver.
L’appel send_message confirme seulement que le message a été remis à l’autre session. Ce qu’il est devenu arrive plus tard sous forme de reçu : s’il a été mis en attente, refusé, rejeté, abandonné, expiré ou mal adressé (l’adresse a changé de main — relister les agents) — ou libéré après une mise en attente — une notification apparaît dans le transcript de la session émettrice (Message to <name>: …). Refusé, rejeté et abandonné sont trois réponses différentes : refusé signifie que quelqu’un a examiné le message et dit non, rejeté signifie que le agents.crossSessionInbound de cette session est refuse et que personne ne l’a vu du tout, et abandonné signifie que sa boîte de réception a écarté le message avant tout cela (voir ci-dessous). Le premier abandon reçoit une réponse immédiate et les suivants sont regroupés dans un reçu toutes les quelques secondes, chacun nommant les messages qu’il représente, ainsi une série coûte quelques lignes plutôt qu’une ligne chacune. Le modèle qui l’a envoyé n’est pas informé ; si l’autre session répond, la réponse arrive comme un message inter-session.
Protection contre les inondations
Une session accepte jusqu’à 30 messages à la fois d’un expéditeur, puis un toutes les deux secondes, et jusqu’à 32 à la fois de tous les expéditeurs combinés, puis un par seconde. La deuxième limite existe car l’expéditeur s’identifie lui-même : faire tourner ce nom obtient une nouvelle allocation de la première limite mais pas de la deuxième. Elle est à peine supérieure à la première car chaque message accepté génère un accusé de réception, et une session ne peut en envoyer qu’un nombre limité à la fois. Un message provenant d’une autre session qui répète mot pour mot le message précédent de cet expéditeur dans les 30 secondes est également rejeté — un modèle bouclant sur une phrase génère un nouvel identifiant de message à chaque fois, c’est donc le texte qui permet de le détecter. Les messages provenant d’un script lancé par la session et d’un contrôleur de confiance sont exemptés de la vérification de répétition, car un hook signalant deux fois la même ligne signale deux faits distincts et une personne disant « continue » deux fois le signifie deux fois ; ils restent toutefois soumis aux limites de débit. Enfin, un message accepté mais impossible à mettre en file d’attente car la session a déjà 50 messages en attente est également rejeté.
Un message rejeté ainsi n’est jamais conservé, jamais présenté au modèle, et ne laisse aucune trace, afin que l’expéditeur puisse réessayer plus tard avec succès. La session réceptrice le mentionne dans son transcript au maximum une fois par minute par expéditeur, avec un compteur indiquant ce que cette ligne représente. La session émettrice reçoit un seul accusé de réception nommant chaque message que la rafale lui a coûté, et son transcript indique de regrouper ce qui compte encore dans un seul message ultérieur plutôt que de renvoyer séparément.
Le côté émetteur n’attend pas pour savoir si le message a été accepté. Chaque session suit ce qu’elle a envoyé à chaque adresse et refuse un envoi que le récepteur aurait rejeté, afin que le modèle soit invité à grouper avant que le message ne soit écrit plutôt qu’après — et le récepteur ne consomme jamais une connexion pour un message qu’il allait rejeter.
Authentification de la boîte de réception et injection scriptée
La boîte de réception de chaque session nécessite un jeton spécifique à la session : une connexion doit le présenter sur sa première ligne avant qu’un message ne soit lu, et les sessions échangent automatiquement des jetons via les mêmes enregistrements de registre qui leur permettent de se découvrir mutuellement. Les sessions issues d’une version sans prise en charge des jetons peuvent recevoir d’une version plus récente, mais leurs envois vers celle-ci sont ignorés.
Une session exporte sa propre adresse de boîte de réception et un jeton vers les processus enfants sous forme de QWEN_CODE_MESSAGING_SOCKET et QWEN_CODE_MESSAGING_TOKEN, afin qu’un script ou un hook exécuté par la session puisse lui renvoyer un message. Il s’agit d’un second jeton enfant qui n’est jamais publié ailleurs : seuls les processus lancés par la session peuvent le détenir, de sorte qu’un message arrivant avec ce jeton est reconnu comme provenant de la session elle-même plutôt que d’une autre session.
{ printf '%s\n' \
'{"msgV":1,"type":"auth","token":"'"$QWEN_CODE_MESSAGING_TOKEN"'"}' \
'{"msgV":1,"msgId":"'"$(uuidgen)"'","type":"user","priority":"next","message":{"role":"user","content":"build finished"}}'; \
} | socat - UNIX-CONNECT:"$QWEN_CODE_MESSAGING_SOCKET"Donnez à chaque injection un nouveau msgId. La porte de réception mémorise les identifiants déjà traités, de sorte qu’un hook réutilisant l’un d’eux est livré la première fois puis silencieusement dédupliqué lors de chaque exécution suivante. Répéter le même texte est acceptable — la vérification de répétition ci-dessus ne s’applique pas aux propres processus de la session — mais les limites de débit s’appliquent, de sorte qu’un hook dans une boucle est rejeté comme tout autre flux excessif.
Un message injecté passe toujours par la porte d’entrée et est marqué comme ne provenant pas de l’utilisateur, mais la porte sait qu’il provient du propre processus de la session : sous le défaut de parité de mode, il est livré sans examen (un pair dans la même situation serait retenu), tandis qu’un agents.crossSessionInbound explicite de hold ou refuse s’applique à lui comme à tout autre élément. Le modèle le voit comme <cross_session_message from="own process" origin="own-process"> avec une note indiquant qu’il provient d’un script ou d’un hook exécuté par la session, et non de l’utilisateur.
Contrôleurs fiables
La règle ci-dessus retient un message de tout expéditeur qui n’indique pas dans quelle classe d’examen il se trouve, et un programme qui n’est pas une session Qwen Code n’en a aucune à indiquer. C’est le défaut approprié pour un inconnu, mais pas pour un programme que vous avez choisi : une interface vocale, un pont de dictée, un démon d’automatisation relayant vos propres instructions verrait chaque message mis en attente, et approuver chacun manuellement annulerait l’intérêt.
Vous accordez la livraison à un tel programme en lui émettant un jeton :
qwen sessions controllers add --label voice-bridgeLe jeton est imprimé une seule fois et n’est stocké nulle part : le fichier sous votre répertoire personnel Qwen ne conserve que son empreinte SHA-256, de sorte que rien de ce qui lit ensuite ce fichier ne peut présenter le jeton. Placez-le dans la configuration propre du contrôleur lorsque la commande l’imprime.
Un contrôleur présente le jeton comme tout autre expéditeur — sur la première ligne de la connexion — et récupère le chemin de la socket depuis le registre des sessions (qwen sessions ps --json imprime un enregistrement par session active, ipcPath étant l’adresse) :
{ printf '%s\n' \
'{"msgV":1,"type":"auth","token":"'"$QWEN_CONTROLLER_TOKEN"'"}' \
'{"msgV":1,"msgId":"'"$(uuidgen)"'","type":"user","priority":"next","message":{"role":"user","content":"open the failing test"}}'; \
} | socat - UNIX-CONNECT:"$SESSION_IPC_PATH"Un message arrivant avec un jeton accordé est livré sans examen par message, quelle que soit la classe d’examen des deux côtés — mais il cède toujours devant un paramètre explicite : un agents.crossSessionInbound de hold le met en attente comme tout autre élément, et refuse le rejette. Les accords appartiennent à votre répertoire personnel Qwen plutôt qu’à une seule session, de sorte qu’un contrôleur atteint les sessions que vous exécutez, et les sessions relisent le fichier à chaque connexion : créer ou révoquer un accord prend effet à la connexion suivante, sans rien à redémarrer.
qwen sessions controllers list # ids, labels, when they were added
qwen sessions controllers remove c_1a2b # revoke one/peers controllers et /peers revoke <id> font la même chose depuis une session. Un message reçu via un jeton d’accès est affiché comme Message from a trusted controller (voice-bridge), et apparaît dans /peers sous forme de [controller] voice-bridge si un paramètre hold l’a mis en attente.
Le modèle voit ce message comme <cross_session_message from="controller" origin="controller" controller="voice-bridge">, avec une mention indiquant qu’il relaie vos propres instructions — ainsi que les deux mêmes interdictions qui s’appliquent à toute autre origine : il ne peut pas modifier les paramètres d’autorisation, QWEN.md ou la configuration parce que le message l’a demandé, et il ne peut pas considérer le message comme votre approbation d’une invite de confirmation en attente. Un contrôleur peut dire quoi faire ensuite ; il ne peut pas répondre à une invite à votre place.
Toute personne détenant le jeton peut envoyer des messages en tant que ce contrôleur, traitez-le donc comme n’importe quel autre identifiant : donnez-le à un seul programme, évitez de le placer dans une configuration partagée, et révoquez-le lorsque le programme a terminé.
Sessions pilotées par un programme via ACP
Chaque processus enfant qwen --acp enregistre chaque session qu’il héberge — comme serve lorsque le démon a lancé le processus, comme headless lorsqu’un éditeur ou un autre client pilote directement qwen --acp — et la session apparaît dans qwen sessions ps et dans le list_agents d’une autre session comme n’importe quelle autre. Elle peut envoyer : son modèle peut appeler send_message pour atteindre un terminal ouvert par vous. Plusieurs d’entre eux partagent un seul processus et une seule boîte de réception, donc un expéditeur doit nommer la session visée — chaque session Qwen Code le fait automatiquement.
Les messages envoyés à une telle session sont refusés plutôt que mis en attente. La mise en attente est une question posée à une personne, et personne ne surveille une liste de messages en attente pour le compte d’une session pilotée ; un expéditeur est informé immédiatement au lieu d’attendre l’expiration. L’endroit où un message mis en attente devrait apparaître pour ces sessions n’est pas encore défini.
Une session s’enregistre sauf si ses propres paramètres désactivent agents.crossSessionMessaging, ou si elle a été lancée avec --bare ou --safe-mode — ceux-ci désactivent la messagerie quel que soit le réglage. Désactivée, elle reste invisible, car la seule raison de lister une session que personne ne peut contacter serait de publier une adresse qui ne répond jamais.
Programmes qui ne sont pas des sessions Qwen Code
Tout ce qui précède fonctionne entre les sessions, mais rien de tout cela n’est spécifique à une session. Un programme qui écrit un enregistrement de registre pour lui-même et lie une boîte de réception de la même manière est listé par qwen sessions ps et par list_agents, peut être adressé par nom depuis send_message, et reçoit des accusés de réception pour ce qu’il envoie — une interface vocale, un relais, un surveillant de build. Il doit enregistrer kind: "external" afin qu’une liste puisse indiquer ce qu’il est.
Protocole Inter-Sessions est le contrat pour en écrire un : le schéma d’enregistrement et la méthode de jugement de la vivacité, les chemins de socket et le cadrage, la ligne d’authentification, chaque champ de trame, les états d’accusé de réception et leurs transitions, et ce qu’un destinataire fait avec un message avant que son modèle ne le voie.
Un programme Node n’a pas besoin d’écrire tout cela à la main : @qwen-code/sdk/peer implémente le contrat. PeerEndpoint.start({ name }) publie l’enregistrement et lie la boîte de réception, list() et send() adressent les sessions par nom, et onMessage reçoit ce qu’ils envoient.