Skip to Content
Guide utilisateurFonctionnalitésCommandes

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éfixeDescription de la fonctionCas d’utilisation typique
Commandes slash (/)Contrôle de Qwen Code au niveau métaGestion des sessions, modification des paramètres, obtention d’aide
Commandes at (@)Injection rapide du contenu de fichiers locaux dans la conversationPermettre à 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èmeExé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.

CommandeDescriptionExemples d’utilisation
/initAnalyser le répertoire actuel et créer le fichier de contexte initial/init
/summaryGénérer un résumé du projet basé sur l’historique des conversations/summary ou /summary docs/my-summary.md
/compressRemplacer l’historique du chat par un résumé pour économiser des Tokens/compress ou /summarize
/compress-fastCompression rapide sans IA — supprime les anciennes sorties d’outils et les parties de réflexion/compress-fast
/resumeReprendre une session de conversation précédente/resume ou /continue
/recapGénérer immédiatement un résumé d’une ligne de la session/recap
/restoreRétablir les fichiers du projet au checkpoint avant l’exécution d’un appel d’outil/restore (liste) ou /restore <ID>
/deleteSupprimer une session précédente/delete
/branchForker la conversation actuelle dans une nouvelle session/branch
/forkLancer un agent en arrière-plan qui hérite de l’intégralité de la conversation/fork <directive>
/rewindRembobiner la conversation à un tour précédent/rewind ou /rollback
/exportExporter l’historique de la session vers un fichier/export html, /export md, /export json, /export jsonl
/renameRenommer ou taguer la session actuelle/rename My Feature ou /tag
/commitCréer un commit git avec un message rédigé par l’IA/commit ou /commit only stage the parser changes
Note

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.

Note

/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.

Note

/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.

CommandeDescriptionExemples d’utilisation
/clearEffacer l’historique des conversations et libérer le contexte/clear, /reset, /new
/contextAfficher la répartition de l’utilisation de la fenêtre de contexte/context
→ detailAfficher la répartition de l’utilisation du contexte par élément/context detail
/historyContrôler les préférences d’affichage et la visibilité de l’historique/history collapse-on-resume, /history expand-on-resume, /history expand-now
/diffOuvrir 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
/logOuvrir une visionneuse de l’historique des commits pour le workspace (Web Shell uniquement)/log
/themeChanger le thème visuel de Qwen Code/theme
/vimActiver/Désactiver le mode d’édition Vim dans la zone de saisie/vim
/voiceActiver/Désactiver la saisie par dictée vocale/voice, /voice hold, /voice tap, /voice off, /voice status
/directoryGérer l’espace de travail avec support multi-répertoires/dir add ./src,./tests, /dir show
/cdDéplacer cette session vers un nouveau répertoire de travail/cd ../other-project
/editorOuvrir la boîte de dialogue pour sélectionner l’éditeur pris en charge/editor
/statuslineOuvrir 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-setupConfigurer 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.

CommandeDescriptionExemples d’utilisation
/languageAfficher 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.

CommandeDescriptionExemples d’utilisation
/mcpLister les serveurs et outils MCP configurés/mcp, /mcp desc, /mcp nodesc, /mcp schema
/import-configImporter des serveurs MCP depuis les configurations Claude/import-config all, /import-config claude-code, /import-config claude-desktop --scope user|project
/toolsAfficher la liste actuelle des outils disponibles/tools, /tools desc
/skillsOuvrir le panneau Skills pour parcourir, rechercher, activer/désactiver et lancer des skills/skills, /<skill-name>
/learnCré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
/curatorInspecter, épingler, archiver ou restaurer les auto-skills de projet inactives/curator, /curator run --dry-run, /curator pin <directory>, /curator restore <directory>
/planPasser en mode plan ou quitter le mode plan/plan, /plan <task>, /plan exit
/approval-modeChanger le mode d’approbation des outils (session actuelle uniquement)/approval-mode, /approval-mode auto-edit
→ planAnalyse uniquement, aucune exécution (revue sécurisée)/approval-mode plan
→ defaultExiger une approbation pour les modifications (usage quotidien)/approval-mode default
→ auto-editApprouver automatiquement les modifications (environnement de confiance)/approval-mode auto-edit
→ autoApprobation évaluée par classifieur (autonome)/approval-mode auto
→ yoloTout approuver automatiquement (prototypage rapide)/approval-mode yolo
/peersExaminer 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>
/modelChanger le modèle utilisé dans la session actuelle/model, /model <model-id> (changer immédiatement)
/model --fastDéfinir un modèle plus léger pour les suggestions de prompts/model --fast qwen3-coder-flash
/model --voiceDéfinir le modèle utilisé pour la transcription vocale/model --voice <model-id>
/model --visionDéfinir le modèle vision-bridge utilisé pour transcrire les images pour un modèle principal textuel/model --vision <model-id>
/model --compactionDéfinir le modèle utilisé pour la compression du chat/model --compaction <model-id>, /model --compaction clear
/model --imageDé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>
/effortDé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-styleChoisir 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)
/extensionsGérer les extensions/extensions list, /extensions manage
→ listLister les extensions installées/extensions list
→ manageGérer les extensions installées (interactif)/extensions manage
→ exploreOuvrir la page des extensions dans le navigateur/extensions explore <Gemini|ClaudeCode>
→ installInstaller une extension depuis un dépôt Git ou un chemin/extensions install <repo-or-path>
/memoryOuvrir la boîte de dialogue du Gestionnaire de mémoire/memory
/rememberSauvegarder une mémoire durable/remember Prefer terse responses
/forgetSupprimer les entrées correspondantes de la mémoire automatique/forget <query>
/dreamExécuter manuellement la consolidation de la mémoire automatique/dream
/hooksGérer les hooks Qwen Code/hooks, /hooks list
/reload-pluginsRecharger les modifications des extensions (commandes, compétences, agents, workflows, hooks, serveurs MCP/LSP) depuis le disque/reload-plugins
/permissionsGérer les règles de permission/permissions
/agentsGérer les sous-agents/agents manage, /agents create
/arenaGérer les sessions Arena/arena start, /arena stop, /arena status, /arena select (alias choose)
/goalDé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
/tasksLister les tâches en arrière-plan/tasks
/workflowsInspecter les exécutions de workflow ; mettre en pause/reprendre coopérativement une exécution en arrière-plan/workflows, /workflows <runId>, /workflows p <runId>
/lspAfficher le statut du serveur LSP/lsp
/trustGérer les paramètres de confiance des dossiers/trust
Warning

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.

Warning

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.

Note

/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.

Note

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.

CommandeDescriptionExemples d’utilisation
/reviewRevue de code multi-agents (12 agents parallèles en effort élevé)/review, /review 123, /review 123 --comment, /review --effort low
/coordinateCoordonner des workers en lecture seule et un writer optionnel dans un worktree/coordinate investigate and fix the authentication regression
/loopExécuter une invite selon un horaire récurrent/loop 5m check the build
/goal-draftTransformer une intention floue en objectif /goal vérifiable/goal-draft make the auth tests pass
/autofix-prSurveiller 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
/simplifyExaminer les modifications récentes et appliquer directement des nettoyages sûrs/simplify, /simplify focus on duplication
/qc-helperRé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.

CommandeDescription
/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) :

RaccourciAction
EscapeAnnuler (pendant le chargement) ou fermer (une fois terminé)
Space ou EnterFermer la réponse (lorsque l’input est vide)
Ctrl+C ou Ctrl+DAnnuler 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 :

ModeComportement
InteractiveAffiche au-dessus du Composer avec le rendu Markdown
Non-interactiveRetourne le résultat texte : btw> question\nanswer
ACP (Agent Protocol)Retourne un générateur asynchrone stream_messages
Tip

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.

CommandeDescription
/advisorRevoir 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, /advisor bloque 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 advisorModel pour 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 :

ModeComportement
InteractiveRend la revue en quatre sections dans la conversation
ACP (Agent Protocol)Renvoie la revue en tant que résultat de message
Tip

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.

Note

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.

CommandeDescription
/recapGé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, /recap affiche 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.
Tip

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 :

ToucheAction
← / →Basculer entre les sources (Current / T1 / T2…)
↑ / ↓Naviguer dans la liste de fichiers
j / kNaviguer dans la liste de fichiers (style vim)
EnterVoir le diff inline pour le fichier sélectionné
← / EscRetourner à la liste de fichiers depuis la vue diff inline
EscFermer 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.md

Web 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 ] │ └───────────────────────────────────────────────────────┘
Note

/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.

CommandeDescriptionExemples d’utilisation
/helpAffiche l’aide pour les commandes disponibles/help ou /?
/statusAffiche les informations de version/status ou /about
/status pathsAffiche les chemins des fichiers et des logs de la session en cours/status paths
/statsOuvre le tableau de bord interactif des statistiques d’utilisation (onglets Session, Activity et Efficiency)/stats ou /usage
/stats modelAffiche la répartition des tokens par modèle et le coût estimé/stats model
/stats toolsAffiche le nombre d’appels par outil/stats tools
/stats skillsAffiche le nombre d’appels par skill pour la session live en cours (live uniquement ; exclut l’activité quotidienne/mensuelle inter-sessions)/stats skills
/stats dailyAffiche les statistiques d’utilisation des tokens par jour/stats daily (alias day), /stats day [YYYY-MM-DD]
/stats monthlyAffiche les statistiques d’utilisation des tokens par mois/stats monthly (alias month), /stats month [YYYY-MM]
/stats exportExporte les statistiques d’utilisation en CSV ou JSON/stats export <daily|monthly> [date|month] [--format csv|json] [--output path]
/settingsOuvre l’éditeur de paramètres/settings
/configObtient 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>
/authChange la méthode d’authentification/auth, /connect, /login
/logoutSe déconnecter du compte Qwen Subscription actif (disponible avec la connexion Qwen Subscription)/logout
/upgradeOuvrir les plans d’abonnement Qwen (disponibles avec la connexion Qwen Subscription)/upgrade
/doctorExécute les diagnostics d’installation et d’environnement/doctor, /doctor memory
→ memoryAffiche les diagnostics de mémoire du processus en cours/doctor memory [--json] [--sample] [--snapshot]
→ cpu-profileEnregistre un profil CPU pour l’analyse dans Chrome DevTools/doctor cpu-profile [--duration <seconds>]
→ rollbackRestaure le binaire CLI standalone à la version précédente (installations standalone uniquement ; pour l’historique de conversation utilisez /rewind)/doctor rollback
/docsOuvre la documentation complète de Qwen Code dans le navigateur/docs
/ideGère l’intégration IDE/ide status, /ide install, /ide enable, /ide disable
/insightGénère des insights de programmation à partir de l’historique du chat/insight
/setup-githubConfigure GitHub Actions/setup-github
/bugSoumet un problème concernant Qwen Code/bug Button click unresponsive
/copyCopie 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
/quitQuitte Qwen Code immédiatement/quit ou /exit
Warning

/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.

Note

/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

RaccourciFonctionNote
Ctrl/cmd+LEffacer l’écranEfface uniquement l’écran visible (ne réinitialise pas la session comme /clear)
Ctrl/cmd+TBasculer la description de l’outilGestion des outils MCP
Ctrl/cmd+C×2Confirmation de sortieMécanisme de sortie sécurisé
Ctrl/cmd+ZAnnuler la saisieÉdition de texte
Ctrl/cmd+Shift+ZRé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.

CommandeDescription
/authConfigurer l’authentification de manière interactive (alias : /connect, /login)
/doctorAfficher les vérifications d’authentification et d’environnement
Note

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 commandeDescriptionExemples
@<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
@ autonomeUtilisé 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 commandeDescriptionExemples
!<shell command>Exécuter une commande dans un sous-Shell!ls -la, !git status
! seulBasculer 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.

Note

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

FonctionDescriptionAvantagesPrioritéScénarios applicables
Espace de noms (Namespace)Un sous-répertoire crée des commandes nommées avec des deux-pointsMeilleure organisation des commandes
Commandes globales~/.qwen/commands/Disponibles dans tous les projetsBasseCommandes personnelles fréquemment utilisées, utilisation multi-projets
Commandes de projet<project root directory>/.qwen/commands/Spécifiques au projet, versionnablesÉlevéePartage 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 fichierCommande généréeExemple 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.
ChampRequisDescriptionExemple
descriptionFacultatifDescription de la commande (affichée dans /help)description: Code analysis tool
Corps du promptRequisContenu du prompt envoyé au modèleTout contenu Markdown après le frontmatter

Format de fichier TOML (Obsolète)

Warning

Obsolète : Le format TOML est encore pris en charge mais sera supprimé dans une future version. Veuillez migrer vers le format Markdown.

ChampRequisDescriptionExemple
promptRequisContenu du prompt envoyé au modèleprompt = "Please analyze code: {{args}}"
descriptionFacultatifDescription de la commande (affichée dans /help)description = "Code analysis tool"

Mécanisme de traitement des paramètres

Méthode de traitementSyntaxeScénarios applicablesFonctionnalité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ètresAucune marque spécialeCommandes simples, ajout de paramètresAjout tel quel
Injection de commande Shell!{command}Besoin de contenu dynamiqueConfirmation d’exécution requise avant

1. Injection contextuelle ({{args}})

ScénarioConfiguration TOMLMéthode d’appelEffet réel
Injection bruteprompt = "Fix: {{args}}"/fix "Button issue"Fix: "Button issue"
Dans une commande Shellprompt = "Search: !{grep {{args}} .}"/search "hello"Exécute grep "hello" .

2. Traitement des paramètres par défaut

Situation d’entréeMéthode de traitementExemple
A des paramètresAjouter à la fin du prompt (séparés par deux sauts de ligne)/cmd parameter → Prompt original + paramètre
Sans paramètresEnvoi du prompt tel quel/cmd → Prompt original

🚀 Injection de contenu dynamique

Type d’injectionSyntaxeOrdre de traitementObjectif
Contenu de fichier@{file path}Traité en premierInjecter des fichiers de référence statiques
Commandes Shell!{command}Traité au milieuInjecter des résultats d’exécution dynamiques
Remplacement de paramètres{{args}}Traité en dernierInjecter des paramètres utilisateur

3. Exécution de commandes Shell (!{...})

OpérationInteraction 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 fichierStatut de prise en chargeMéthode de traitement
Fichiers texte✅ Prise en charge complèteInjection directe du contenu
Images/PDF✅ Prise en charge multimodaleEncodage et injection
Fichiers binaires⚠️ Prise en charge limitéePeut être ignoré ou tronqué
Répertoire✅ Injection récursiveSuit 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érationCommande/Code
1. Créer la structure de répertoiresmkdir -p ~/.qwen/commands/refactor
2. Créer le fichier de commandetouch ~/.qwen/commands/refactor/pure.md
3. Éditer le contenu de la commandeSe 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 unchanged

Résumé des bonnes pratiques pour les commandes personnalisées

Tableau des recommandations de conception de commandes

Points de pratiqueApproche recommandéeÀ éviter
Nommage des commandesUtiliser des espaces de noms pour l’organisationÉviter les noms trop génériques
Traitement des paramètresUtiliser clairement {{args}}S’appuyer sur l’ajout par défaut (facile à confondre)
Gestion des erreursExploiter la sortie d’erreur ShellIgnorer l’échec d’exécution
Organisation des fichiersOrganiser par fonction dans des répertoiresToutes les commandes dans le répertoire racine
Champ DescriptionToujours fournir une description claireSe fier à la description générée automatiquement

Tableau de rappel des fonctionnalités de sécurité

Mécanisme de sécuritéEffet de protectionOpération utilisateur
Échappement ShellEmpêche l’injection de commandeTraitement automatique
Confirmation d’exécutionÉvite l’exécution accidentelleConfirmation par dialogue
Rapport d’erreurAide au diagnostic des problèmesConsulter 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

CommandeDescriptionExemples d’utilisation
qwen sessions listListe les sessions de conversation récentesqwen sessions list, qwen sessions list --json --limit 50
qwen sessions psListe les sessions interactives en cours d’exécutionqwen sessions ps, qwen sessions ps --json
qwen sessions controllersGérer les tokens de contrôleurs fiablesqwen 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 :

OptionTypeDéfautDescription
--jsonbooleanfalseSortie au format JSON Lines (un objet JSON par ligne)
--limitnumber20Nombre 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, cwd

L’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 :

OptionTypeDéfautDescription
--jsonbooléenfalseSortie 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: true

Rien 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 .cwd

6. 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-bridge

Le 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.

Last updated on