Modo CLI compatible con IA Server
A partir de Babel Licensing 11.8, la línea de comandos lic puede emitir un flujo de salida estructurado y legible por máquina, adecuado para pipelines de CI, sistemas de pedidos y agentes de IA, igual que el modo que el ofuscador incorporó en la versión 11.7.
La salida de texto predeterminada de lic no cambia y sigue siendo totalmente compatible con las versiones anteriores: los scripts existentes no requieren ningún cambio.
El modo compatible con IA se activa con tres opciones globales:
--format=text|json|ndjsonselecciona el formato del canal de salida--quiet(alias-q) suprime el banner con el logotipo y hace que las solicitudes interactivas fallen de inmediato--strict-exitactiva los códigos de salida semánticos
Cuando se selecciona --format=json o --format=ndjson, stdout transporta el flujo estructurado y los mensajes legibles por personas se envían a stderr, de modo que los dos canales nunca se entremezclan.
--format es también la opción que selecciona el formato de salida de la licencia (xml, serial, base32, ascii). Los dos conjuntos de valores son disjuntos, así que ambos significados pueden aparecer en una misma línea de comandos: lic MyApp.dll --format base32 --format json.
Opciones
—format <format>
Selecciona el formato de salida que se usa en stdout. Valores permitidos:
| Valor | Descripción |
|---|---|
text | Predeterminado. Salida de consola heredada, legible por personas. |
json | Un único documento JSON almacenado en búfer, que se escribe cuando termina la ejecución (o con --help / --version). Es la mejor opción cuando stdout se captura en un archivo o se canaliza hacia un consumidor de JSON. |
ndjson | JSON delimitado por saltos de línea. Un evento por línea, que se vuelca en cuanto se produce. Es la mejor opción para los consumidores de flujos, los reenviadores de registros y los agentes en tiempo real. |
lic MyApp.dll --keyfile keys.pem --sign --expiredate 365 --format json > result.json
lic MyApp.dll --keyfile keys.pem --sign --format ndjson | jq -c 'select(.level=="error")'Con json o ndjson, el banner con el logotipo se suprime con independencia de --logo, de modo que el primer byte de stdout sea JSON válido.
—quiet (-q)
Suprime el banner de copyright y todas las solicitudes interactivas. La única solicitud que tiene lic es la contraseña de un archivo de claves PFX: con --quiet, si falta --keypwd se produce un error explícito en lugar de un bloqueo a la espera de la entrada, lo que hace que la opción sea segura para las ejecuciones desatendidas en ejecutores de CI, en contenedores y desde agentes.
lic MyApp.dll --quiet --keyfile signing.pfx --keypwd "$KEY_PWD" --sign--quiet es independiente de --format: se puede combinar con la salida text para conservar los registros legibles por personas sin el banner.
—strict-exit
Hace que el proceso use códigos de salida semánticos. Sin esta opción, lic conserva el contrato heredado, en el que 0 significa éxito y 1 significa cualquier fallo.
| Código de salida | Constante | Significado |
|---|---|---|
0 | success | El comando se completó sin errores. |
10 | invalidArguments | No se pudo analizar la línea de comandos o esta contenía un valor no válido (por ejemplo, una opción desconocida). |
20 | inputNotFound | No se encontró el ensamblado, el archivo de licencia u otro archivo de entrada necesario. |
30 | processingFailure | Falló el procesamiento de la licencia: la generación, la actualización o una firma que no se pudo verificar. |
40 | licensingFailure | La licencia de Babel Licensing de la propia herramienta falta, no es válida o ha caducado. |
50 | keyOrSigningFailure | No se pudo cargar un archivo o un contenedor de claves, o falló una operación criptográfica. |
Los números son los mismos que los de la tabla de --strict-exit del ofuscador, así que un mismo programa puede controlar babel y lic con una sola tabla de códigos de salida; la única diferencia es que el código 30 significa aquí procesamiento de la licencia y allí ofuscación. La clasificación también se expone como exitReason en el resultado JSON, incluso cuando --strict-exit no está activa.
lic MyApp.licenses --verify --keyfile keys.pem --strict-exit --quiet
echo "exit=$?"Esquema: lic.cli.v1
Todas las cargas útiles estructuradas llevan "schema": "lic.cli.v1" y un kind que indica qué es el documento: event, result, help o version. El esquema reproduce el babel.cli.v1 del ofuscador, pero tiene su propia numeración de versiones, porque las dos herramientas exponen conjuntos de opciones distintos. Dentro de una versión principal del esquema se permiten los cambios aditivos; los cambios incompatibles cambiarán el nombre del esquema.
Registro de evento
Cada mensaje que se emite mientras una ejecución está en curso se convierte en un evento:
{
"schema": "lic.cli.v1",
"kind": "event",
"ts": "2026-09-03T06:31:54.1686900Z",
"level": "info",
"message": "License saved to 'MyApp.licenses'"
}| Campo | Tipo | Notas |
|---|---|---|
ts | cadena (ISO 8601, UTC) | Marca de tiempo del momento en que se produjo el evento. |
level | debug | info | warning | error | Gravedad. |
code | cadena | Código de diagnóstico, presente solo cuando el mensaje tiene uno. |
message | cadena | Mensaje legible por personas. |
data | objeto | Carga útil estructurada opcional, presente solo cuando se adjunta. |
Sobre de resultado
—format=json
Cuando la ejecución termina, se escribe en stdout un único objeto JSON. Contiene el resumen de la ejecución y todos los eventos almacenados en búfer durante ella:
{
"schema": "lic.cli.v1",
"kind": "result",
"exitCode": 0,
"exitReason": "success",
"elapsedMs": 133,
"warnings": 0,
"errors": 0,
"events": [
{ "schema": "lic.cli.v1", "kind": "event", "ts": "2026-09-03T06:31:54.1686900Z", "level": "info", "message": "License saved to 'MyApp.licenses'" }
]
}Una ejecución fallida indica la clase de fallo en exitReason y el error entre los eventos. En este caso, el ensamblado de entrada no existía:
{
"schema": "lic.cli.v1",
"kind": "result",
"exitCode": 20,
"exitReason": "inputNotFound",
"elapsedMs": 34,
"warnings": 0,
"errors": 1,
"events": [
{ "schema": "lic.cli.v1", "kind": "event", "ts": "2026-09-03T06:30:27.4366510Z", "level": "error", "message": "Error: The specified file '/build/missing.dll' was not found." }
]
}—format=ndjson
Cada evento se vuelca en cuanto se produce, en su propia línea. Después del último evento se añade una línea final con el resultado, sin la matriz events, puesto que los eventos ya se han transmitido:
{"schema":"lic.cli.v1","kind":"event","ts":"2026-09-03T06:31:54.3357790Z","level":"info","message":"License saved to 'MyApp.licenses'"}
{"schema":"lic.cli.v1","kind":"result","exitCode":0,"exitReason":"success","elapsedMs":141,"warnings":0,"errors":0}| Campo | Tipo | Notas |
|---|---|---|
exitCode | entero | Código de salida numérico que el proceso devuelve realmente (heredado o estricto, según --strict-exit). |
exitReason | cadena | Token de clasificación estable. Refleja siempre la clase semántica, incluso sin --strict-exit. |
elapsedMs | entero | Duración total en tiempo de reloj, en milisegundos. |
warnings | entero | Número de eventos de nivel warning. |
errors | entero | Número de eventos de nivel error. |
events | matriz | Presente en el modo json; se omite en ndjson. |
—help legible por máquina
lic --help --format=json emite una descripción completa de todas las opciones públicas, adecuada para las herramientas que necesitan inspeccionar la superficie de la CLI: autocompletado del shell, agentes de IA, generadores de documentación.
{
"schema": "lic.cli.v1",
"kind": "help",
"version": "12.0.0.0",
"usage": "lic.exe <assembly|licensefile> [<other assemblies>...] [options]",
"options": [
{
"name": "trial",
"aliases": [],
"description": "Add or update trial license restriction",
"args": "<key=value>",
"argRequired": true,
"argOptional": false,
"negatable": false,
"incremental": false,
"container": "hash",
"type": "string",
"group": "- License Restrictions -",
"details": "Set trial restriction properties entering key-value pairs:\n\nid=<id> Restriction id\nexpire=<date> Set expiration date\ndays=<n> Set number of trial days\n..."
}
]
}| Campo | Significado |
|---|---|
name, aliases | El nombre de la opción y sus formas alternativas, incluidas las formas negadas y los alias de una sola letra. |
args | El marcador de posición del argumento tal como aparece en el mensaje de uso, o vacío si la opción no lleva argumento. |
argRequired, argOptional | Si la opción lleva un argumento obligatorio o uno opcional. |
negatable | Si la opción acepta el prefijo no. |
container | scalar para un único valor, array para una opción repetible, hash para pares key=value. |
type | string o integer. |
group | La sección de la salida de ayuda a la que pertenece la opción. |
details | La descripción ampliada, el mismo texto que muestra lic --help <option>. |
También se admite una forma acotada: lic --help trial --format=json emite el mismo sobre solo con la opción trial. Las opciones ocultas e internas no se devuelven nunca.
—version legible por máquina
lic --version --format=json emite información sobre el producto, la versión, el entorno de ejecución y la plataforma:
{
"schema": "lic.cli.v1",
"kind": "version",
"product": "Babel Licensing",
"version": "12.0.0.0",
"fileVersion": "12.0.0.1",
"runtime": ".NET 10.0.0",
"platform": "osx-arm64"
}El campo platform usa el identificador de entorno de ejecución (RID) de .NET en .NET 5 y versiones posteriores, y una cadena sintética <os>-<arch> en los destinos heredados.
Controlar lic desde un agente
Un agente que nunca ha visto lic puede manejarlo solo con la ayuda en JSON: lee el esquema de opciones, construye la línea de comandos a partir de las indicaciones de args y container, ejecuta con --format json --quiet --strict-exit y decide según exitReason. Un ciclo típico para emitir una licencia tiene este aspecto:
lic --help --format json > lic-options.json
lic MyApp.dll --keyfile keys.pem --sign --licensee name="Contoso" --expiredate 365 --output MyApp.licenses --format json --quiet --strict-exit > result.json
jq -r '.exitReason' result.jsonEl mismo contrato, los mismos códigos de salida y los mismos nombres de opciones se aplican a la línea de comandos del ofuscador, documentada en Modo compatible con IA del manual del ofuscador, así que una sola integración cubre las dos herramientas.
Compatibilidad con versiones anteriores
- El valor predeterminado de
--formatestext; la salida de texto heredada, los códigos de salida y el comportamiento no cambian cuando no se especifica ninguna de las opciones nuevas. - Sin
--strict-exit, el proceso sigue devolviendo0en caso de éxito y1ante cualquier fallo, así que las comprobaciones existentes que deciden según$?siguen funcionando. --quietes independiente y se puede activar sin activar la salida estructurada.