Skip to Content
New release 11.5 available 🎉
ObfuscatorCommand LineAI-Friendly Mode

AI-Friendly CLI Mode

Starting with Babel Obfuscator 11.7.0, the command line tool can emit a structured, machine-readable output stream that is well suited to CI pipelines, build orchestrators and AI/agent integrations.

The default text output of babel.exe is unchanged and remains fully backward compatible: existing CI scripts and customer integrations require no changes.

The AI-friendly mode is enabled by three new global flags:

When --format=json or --format=ndjson is selected, stdout carries the structured stream and human-readable diagnostics are routed to stderr so the two channels never interleave.

Flags

—format <format>

Selects the output format used on stdout. Allowed values:

ValueDescription
textDefault. Legacy human-readable console output. No structural changes from previous releases.
jsonBuffered single JSON envelope written when the run completes (or on --help / --version). Best when stdout is captured to a file or piped into a JSON consumer.
ndjsonNewline-delimited JSON. One event per line, flushed as it is produced. Best for streaming consumers, log shippers and live agents that need to react before the run terminates.

Examples:

babel myapp.exe --format=json > result.json babel myapp.exe --format=ndjson | jq -c 'select(.level=="error")'

With —format=json or —format=ndjson the logo banner is automatically suppressed regardless of —logo, so that the very first byte on stdout is valid JSON.

—quiet (-q)

Suppresses the copyright/logo banner and changes the behavior of interactive password prompts: instead of blocking on Console.In, Babel fails fast with an explicit error. This makes --quiet safe for unattended invocations from CI runners, container build steps and AI agents.

babel myapp.exe --quiet --keyfile mykey.pfx --keypwd env:KEY_PWD

--quiet is independent from --format: it can be combined with the legacy text output to keep human-readable logs without the banner.

—strict-exit

Opts the process into semantic exit codes. Without this flag, Babel preserves the legacy contract where 0 means success and 1 means any failure.

Exit codeConstantMeaning
0successRun completed without errors.
10invalidArgumentsCommand line could not be parsed or contained an invalid value (e.g. unknown --format).
20inputNotFoundThe primary assembly or another required input file was not found.
30obfuscationFailureObfuscation failed at runtime (any unclassified obfuscator exception).
40licensingFailureLicensing check failed (missing, expired or unauthorized license).
50keyOrSigningFailureStrong-name signing or cryptographic key operation failed.

The classification is also surfaced as exitReason in the JSON/NDJSON result record (see Result envelope), even when --strict-exit is not active, so consumers can distinguish failure categories independently from the numeric exit code.

babel myapp.exe --strict-exit --format=json echo "exit=$?"

Schema: babel.cli.v1

All structured payloads conform to the versioned babel.cli.v1 schema. Within a major schema version, additive changes (new fields, new event codes, new exit reasons) are allowed; breaking changes will bump the schema name.

Event record

Every diagnostic emitted while a run is in progress is mapped to an event:

event
{ "ts": "2026-05-08T14:32:11.482Z", "level": "info", "code": "BAB1234", "message": "Renaming phase, elapsed time 00.082s", "data": { "phase": "renaming", "elapsedMs": 82 } }
FieldTypeNotes
tsstring (ISO-8601, UTC)Timestamp at which the event was produced.
leveldebug | info | warning | errorSeverity.
codestring | nullBabel diagnostic code (e.g. BAB1234, W00013) when applicable.
messagestringHuman-readable message.
dataobject | nullOptional structured payload attached to the event.

Result envelope

—format=json

A single JSON object is written to stdout when the run terminates. It contains the run-level summary and all events buffered during the run:

result (json)
{ "exitCode": 0, "exitReason": "success", "elapsedMs": 4218, "warnings": 1, "errors": 0, "events": [ { "ts": "2026-05-08T14:32:09.500Z", "level": "info", "code": null, "message": "Babel Obfuscator 11.7.0.0", "data": null }, { "ts": "2026-05-08T14:32:11.482Z", "level": "info", "code": "BAB1234", "message": "Renaming phase ...", "data": { "phase": "renaming" } }, { "ts": "2026-05-08T14:32:13.012Z", "level": "warning", "code": "W00013", "message": "Could not resolve ...", "data": null } ] }

—format=ndjson

Each event is flushed as soon as it is produced, on its own line. After the last event, a final result line is appended (without an events array, since events have already been streamed):

result (ndjson)
{"ts":"2026-05-08T14:32:09.500Z","level":"info","code":null,"message":"Babel Obfuscator 11.7.0.0","data":null} {"ts":"2026-05-08T14:32:11.482Z","level":"info","code":"BAB1234","message":"Renaming phase ...","data":{"phase":"renaming"}} {"ts":"2026-05-08T14:32:13.012Z","level":"warning","code":"W00013","message":"Could not resolve ...","data":null} {"exitCode":0,"exitReason":"success","elapsedMs":4218,"warnings":1,"errors":0}
FieldTypeNotes
exitCodeintegerNumeric exit code actually returned by the process (legacy or strict, depending on --strict-exit).
exitReasonstringStable classification token. Always reflects the semantic class even without --strict-exit.
elapsedMsintegerTotal wall-clock duration in milliseconds.
warningsintegerCount of warning-level events.
errorsintegerCount of error-level events.
eventsarray | nullPresent in json mode; omitted in ndjson (events are streamed as separate lines).

Machine-readable —help

babel --help --format=json emits a complete description of every public option, suitable for tooling that needs to introspect the CLI surface (shell completions, AI agents, doc generators):

--help --format=json (excerpt)
{ "version": "11.7.0.0", "usage": "babel.exe <primary assembly source> [<other assemblies>...] [options]", "options": [ { "name": "controlflow", "aliases": ["nocontrolflow", "no-controlflow", "control-flow", "no-control-flow", "i"], "description": "Enable ([no]disable) MSIL control flow obfuscation", "args": null, "argRequired": false, "argOptional": false, "negatable": true, "incremental": false, "container": "scalar", "type": "boolean", "group": "- Code Obfuscation -", "details": "Use this option to alter the method control flow ..." } ] }

A scoped form is also supported. babel --help controlflow --format=json emits the same envelope but containing only the controlflow option (and its details resolved from the option resource bundle).

Hidden/internal options are never returned.

Machine-readable —version

babel --version --format=json emits runtime and platform information:

--version --format=json
{ "product": "Babel Obfuscator", "version": "11.7.0.0", "fileVersion": "11.7.0.0", "runtime": ".NET 8.0.11", "platform": "win-x64" }

The platform field uses the .NET RuntimeIdentifier (RID) when running on .NET 5+, and a synthetic <os>-<arch> string on legacy targets (net472-x64, unix-x64, …).

Backward compatibility

  • The default value of --format is text; the legacy textual output, exit codes and behavior are unchanged when no new flag is specified.
  • Without --strict-exit, the process keeps returning 0 on success and 1 on any failure — existing CI gates that branch on $? keep working.
  • --quiet is independent and can be opted into without enabling structured output.

The structured output is also available through the MSBuild Task and the Babel.Obfuscator NuGet Package by passing the same flags via the standard property/argument plumbing.

Last updated on