Le CLI de Cursor Agent propose plusieurs formats de sortie avec l’option --output-format lorsqu’elle est utilisée avec --print. Ces formats incluent des formats structurés pour un usage programmatique (json, stream-json) et un format texte simplifié pour un suivi de progression lisible.
Le --output-format par défaut est stream-json. Cette option n’est valable qu’en mode impression (--print) ou lorsque ce mode est déduit (stdout non TTY ou stdin acheminé via un pipe).

Format JSON

Le format de sortie json émet un unique objet JSON (suivi d’un saut de ligne) quand l’exécution se termine avec succès. Les deltas et les événements d’outils ne sont pas émis ; le texte est agrégé dans le résultat final. En cas d’échec, le processus se termine avec un code non nul et écrit un message d’erreur sur stderr. Aucun objet JSON bien formé n’est émis en cas d’échec.

Réponse en cas de succès

En cas de succès, la CLI renvoie un objet JSON avec la structure suivante :
{
  "type": "result",
  "subtype": "success",
  "is_error": false,
  "duration_ms": 1234,
  "duration_api_ms": 1234,
  "result": "<full assistant text>",
  "session_id": "<uuid>",
  "request_id": "<optional request id>"
}
ChampDescription
typeToujours "result" pour les résultats finaux
subtypeToujours "success" pour les exécutions réussies
is_errorToujours false pour les réponses réussies
duration_msTemps d’exécution total en millisecondes
duration_api_msTemps de requête API en millisecondes (actuellement égal à duration_ms)
resultTexte complet de la réponse de l’assistant (concaténation de tous les deltas de texte)
session_idIdentifiant de session unique
request_idIdentifiant de requête optionnel (peut être omis)

Format JSON de flux

Le format de sortie stream-json émet du JSON délimité par des nouvelles lignes (NDJSON). Chaque ligne contient un seul objet JSON représentant un événement en temps réel pendant l’exécution. Le flux se termine par un événement terminal result en cas de succès. En cas d’échec, le processus se termine avec un code non-zéro et le flux peut se terminer prématurément sans événement terminal ; un message d’erreur est écrit sur stderr.

Types d’événements

Initialisation du système

Émis une fois au début de chaque session :
{
  "type": "system",
  "subtype": "init",
  "apiKeySource": "env|flag|login",
  "cwd": "/absolute/path",
  "session_id": "<uuid>",
  "model": "<model display name>",
  "permissionMode": "default"
}
Des champs futurs comme tools et mcp_servers pourront être ajoutés à cet événement.

Message utilisateur

Contient le prompt d’entrée de l’utilisateur :
{
  "type": "user",
  "message": {
    "role": "user",
    "content": [{ "type": "text", "text": "<prompt>" }]
  },
  "session_id": "<uuid>"
}

Delta de texte de l’assistant

Émis plusieurs fois pendant que l’assistant génère sa réponse. Ces événements contiennent des fragments de texte incrémentaux :
{
  "type": "assistant",
  "message": {
    "role": "assistant",
    "content": [{ "type": "text", "text": "<delta chunk>" }]
  },
  "session_id": "<uuid>"
}
Concatène toutes les valeurs message.content[].text dans l’ordre pour reconstituer la réponse complète de l’assistant.

Événements d’appel d’outil

Les appels d’outils sont suivis avec des événements de début et de fin : Appel d’outil démarré :
{
  "type": "tool_call",
  "subtype": "started",
  "call_id": "<string id>",
  "tool_call": {
    "readToolCall": {
      "args": { "path": "file.txt" }
    }
  },
  "session_id": "<uuid>"
}
Appel d’outil terminé :
{
  "type": "tool_call",
  "subtype": "completed",
  "call_id": "<string id>",
  "tool_call": {
    "readToolCall": {
      "args": { "path": "file.txt" },
      "result": {
        "success": {
          "content": "file contents...",
          "isEmpty": false,
          "exceededLimit": false,
          "totalLines": 54,
          "totalChars": 1254
        }
      }
    }
  },
  "session_id": "<uuid>"
}

Types d’appels d’outils

Outil de lecture de fichier :
  • Démarré : tool_call.readToolCall.args contient { "path": "file.txt" }
  • Terminé : tool_call.readToolCall.result.success contient les métadonnées et le contenu du fichier
Outil d’écriture de fichier :
  • Démarré : tool_call.writeToolCall.args contient { "path": "file.txt", "fileText": "content...", "toolCallId": "id" }
  • Terminé : tool_call.writeToolCall.result.success contient { "path": "/absolute/path", "linesCreated": 19, "fileSize": 942 }
Autres outils :
  • Peuvent utiliser la structure tool_call.function avec { "name": "tool_name", "arguments": "..." }

Résultat terminal

L’événement final émis lors d’une exécution réussie :
{
  "type": "result",
  "subtype": "success",
  "duration_ms": 1234,
  "duration_api_ms": 1234,
  "is_error": false,
  "result": "<full assistant text>",
  "session_id": "<uuid>",
  "request_id": "<optional request id>"
}

Séquence d’exemple

Voici une séquence NDJSON représentative montrant le flux typique d’événements :
{"type":"system","subtype":"init","apiKeySource":"login","cwd":"/Users/user/project","session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff","model":"Claude 4 Sonnet","permissionMode":"default"}
{"type":"user","message":{"role":"user","content":[{"type":"text","text":"Lis le README.md et fais-moi un résumé"}]},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"Je vais "}]},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"lire le fichier README.md"}]},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"tool_call","subtype":"started","call_id":"toolu_vrtx_01NnjaR886UcE8whekg2MGJd","tool_call":{"readToolCall":{"args":{"path":"README.md"}}},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"tool_call","subtype":"completed","call_id":"toolu_vrtx_01NnjaR886UcE8whekg2MGJd","tool_call":{"readToolCall":{"args":{"path":"README.md"},"result":{"success":{"content":"# Projet\n\nCeci est un projet d'exemple...","isEmpty":false,"exceededLimit":false,"totalLines":54,"totalChars":1254}}}},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":" et te faire un résumé"}]},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"tool_call","subtype":"started","call_id":"toolu_vrtx_01Q3VHVnWFSKygaRPT7WDxrv","tool_call":{"writeToolCall":{"args":{"path":"summary.txt","fileText":"# Résumé du README\n\nCe projet contient...","toolCallId":"toolu_vrtx_01Q3VHVnWFSKygaRPT7WDxrv"}}},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"tool_call","subtype":"completed","call_id":"toolu_vrtx_01Q3VHVnWFSKygaRPT7WDxrv","tool_call":{"writeToolCall":{"args":{"path":"summary.txt","fileText":"# Résumé du README\n\nCe projet contient...","toolCallId":"toolu_vrtx_01Q3VHVnWFSKygaRPT7WDxrv"},"result":{"success":{"path":"/Users/user/project/summary.txt","linesCreated":19,"fileSize":942}}}},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"result","subtype":"success","duration_ms":5234,"duration_api_ms":5234,"is_error":false,"result":"Je vais lire le fichier README.md et te faire un résumé","session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff","request_id":"10e11780-df2f-45dc-a1ff-4540af32e9c0"}

Format texte

Le format de sortie text fournit un flux simplifié et lisible par des humains des actions de l’agent. Au lieu d’événements JSON détaillés, il produit des descriptions textuelles concises de ce que l’agent fait en temps réel. Ce format est utile pour suivre l’avancement de l’agent sans le coût de l’analyse de données structurées, ce qui le rend idéal pour la journalisation, le débogage ou un simple suivi de progression.

Exemple de sortie

Read file
Edited file
Ran terminal command
Created new file
Chaque action apparaît sur une nouvelle ligne au moment où l’agent l’exécute, offrant un retour immédiat sur la progression de l’agent dans la tâche.

Notes d’implémentation

  • Chaque événement est émis sur une seule ligne terminée par \n
  • Les événements thinking sont supprimés en mode impression et n’apparaîtront dans aucun des deux formats de sortie
  • Des ajouts de champs peuvent survenir au fil du temps de manière rétrocompatible (les consommateurs doivent ignorer les champs inconnus)
  • Le format de flux fournit des mises à jour en temps réel, tandis que le format JSON attend la fin avant de produire les résultats
  • Concatène tous les deltas de message assistant pour reconstruire la réponse complète
  • Les ID d’appel d’outil peuvent être utilisés pour corréler les événements de début/fin
  • Les ID de session restent cohérents tout au long d’une seule exécution d’agent