Repository navigation
Releases: facturadirecta/cli
Releases · facturadirecta/cli
Release list
v0.17.0
Añadido
facturadirecta query --limit-per-group N: con dos dimensiones, como
máximo N filas de la segunda dentro de cada valor de la primera («los tres
productos más vendidos a cada cliente»).facturadirecta query --amounts company: los importes deinvoices,
billsy sus líneas en la moneda de la empresa, en un solo grupo aunque
haya varias monedas (document, por defecto, los separa por moneda).
Cambiado
facturadirecta queryadmite las fuentesinvoiceLinesybillLines
(líneas de facturas de venta y compra) con los mismos permisos que
invoicesybills; la ayuda y los errores de--fromlas enumeran.- La skill que instala el CLI y el README enseñan a sacar los productos más
vendidos y las compras por producto coninvoiceLinesybillLines, y
avisan de que los cobros a fondo y el margen dependen del plan
(plan_limit_exceeded).
v0.16.2
Cambiado
- La ayuda larga de
invoices createeinvoices updateexplica que
emitir una factura (main.draftafalse) le asigna número y, con
VeriFactu o TicketBAI activos, genera el registro de facturación y lo
envía a la AEAT o a la Diputación Foral en ese momento, sin vuelta atrás
(solo anular, rectificar o subsanar); que anular (main.voidedatrue)
tampoco se revierte; que una factura emitida con VeriFactu solo admite
cambios subsanables y con TicketBAI ninguno; y que sinmain.draftse
aplicasales.newInvoiceModede la empresa, que puede serfinal. - La skill pide crear siempre como borrador y emitir, anular o subsanar
solo cuando el usuario lo pida para esa factura y tras avisarle. - El contrato vendorizado trae las descripciones nuevas de
createInvoice,
updateInvoice,main.draftymain.voided(describelas muestra), y
las notas dedescribede esas dos acciones se quedan con lo que el
contrato no dice: borrador siempre, la ventana de fechas de VeriFactu, no
subsanar por cuenta propia y restaurar una anulada solo sin datos de
VeriFactu, TicketBAI ni Batuz.
v0.16.1
Cambiado
- El contrato vendorizado es el de FacturaDirecta 4.1.13:
queryadmite
fiscalIdycontacts(describe querylos explica), el--datade
contactos y documentos de venta admitelanguage, yapi list_activity
filtra también por los tiposdelegatedRenewalRevertedy
partnerDelegatedRenewalReverted. describedequery,get_results_summary,list_results_detail,
get_profit_lossyget_balance_sheetexplica que el tope de 5 años del
periodo cuenta el primer y el último día: «los últimos 5 años» hasta el
2026-10-19 empiezan el 2021-10-20, y con el 2021-10-19 la API responde 400.facturadirecta query: la ayuda de--byincluyefiscalId(agrupa por
el identificador fiscal y reúne los contactos duplicados con el mismo NIF)
y la de--measures,contacts(cuántos contactos hay detrás de cada
grupo). Los ejemplos, el README y la skill añaden los mejores clientes por
NIF y la búsqueda de contactos duplicados. En la tabla, la columna
fiscalIdmuestra el NIF delante del nombre.--summaryde contactos y documentos de venta incluyelanguage(el
idioma en que se imprimen y se envían sus documentos) cuando tiene valor;
sin él se usa el idioma base de la plantilla.
v0.16.0
Añadido
facturadirecta tax-declarations: los modelos de impuestos que la
empresa ha generado y guardado (303, 111, 115, 130, 202, 180, 190, 347,
349 y 390), de solo lectura:list(por modelo, ejercicio y periodo, con
el resultado y si tiene fichero AEAT;--related boxesañade las
casillas),get(las casillas;--related records, los registros por
tercero de las informativas),pdf,aeat-file(url y filename del
fichero de presentación) yattachments list.facturadirecta query: la consulta analítica de la API (POST /query),
la misma acciónquerydel servidor MCP. Una fuente (--from invoices,
bills,contactsojournal), medidas (--measures), hasta dos
dimensiones (--by), un periodo abreviado (--period 2026,2026-Q3,
2026-09,2026-01-01..2026-06-30) con comparativa (--compare) o
desglose (--breakdown), filtros (--filter "state in overdue"), orden,
--limity--other; o la petición completa con--data. En la terminal,
una tabla con los grupos, la fila de otros y los totales; con-jo-q,
el JSON de la API. Responde en una llamada «mis cinco mejores clientes»,
«¿cuánto suman las facturas vencidas?» o «gastos por proveedor» sin
paginar.journalexige el módulo de Contabilidad, comojournal.--totalseninvoices listybills list: la respuesta añadetotals
con el recuento y la suma de la base imponible, los impuestos, el total y
el pendiente de todo lo que cumple los filtros, por moneda; en la terminal
sale bajo la tabla y--summarylo conserva (-qsolo da los elementos).describemuestra los ejemplos de cuerpo del propio contrato en las
operaciones que api-docs aún no documenta (describe query --example).
Cambiado
- El contrato vendorizado es el de producción (FacturaDirecta 4.1.12), con
la consulta analítica y las declaraciones de impuestos. El login deja de
pedir los scopes que Keycloak aún no conozca (contract.PendingScopes,
hoy vacío).
v0.15.0
Añadido
facturadirecta banks get <id>: un banco por su id, con la misma forma que
cada elemento del listado y--url.--relatedenbanks listybanks get: añade bajorelatedel saldo
contable (balance, el de la pantalla de bancos y el que sirve para la
contabilidad), el saldo según la entidad (linkedBalance), el estado de la
conexión automática (link) y los movimientos pendientes de conciliar
(statements); repetido o separado por comas.--balance-date AAAA-MM-DD
da el saldo contable al cierre de ese día y pidebalancepor sí sola.
En la terminal,banks listmuestra una tabla con las columnas de lo que
se pida.facturadirecta settings company: la ficha de la empresa y su forma de
trabajar (datos fiscales, moneda, modo borrador o definitivo, impuestos,
numeración, bloqueo contable, VeriFactu y TicketBAI, buzón de la bandeja y
módulos del plan);--urlda la página de ajustes en la web.
Cambiado
facturadirecta bankspasa a ser un grupo, comostatements: el listado es
ahorafacturadirecta banks list(con las mismas flags).
v0.14.0
Añadido
facturadirecta api <operación> [ids…](ADR-0008): llama a cualquier
operación de la API por su nombre de acción (el dedescribey del servidor
MCP) o su operationId, también las que no tienen comando propio (pedidos,
órdenes de compra, versiones, campos personalizados, stock, actividad…).- Los ids de la ruta van como argumentos y la query con
-p nombre=valor;
el cuerpo, con--data '<json>',--data @ficheroo por stdin. --idempotency-keyla envía donde la espera la operación;--dry-run
imprime la petición, sin credenciales, sin enviarla;--outputguarda la
respuesta.- Las escrituras necesitan
login --scope fully los borrados
irreversibles, confirmación (--yes), como los comandos dedicados. describeañade la invocación genérica (cli.api).
- Los ids de la ruta van como argumentos y la query con
- La salida JSON (también la de
--jqy la de los errores en modo agente) ya
no escapa<,>ni&como\u003c,\u003ey\u0026: los textos y las
formas de uso (<id>) se leen tal cual. Sigue siendo el mismo JSON. commands.json(la superficie que publica cada release) añade, en cada
comando, las operaciones de la API a las que llama (operations, con
operationIdyaction), yapiOnly, las operaciones sin comando
dedicado, que se llaman confacturadirecta api. Son campos nuevos: los
existentes no cambian.facturadirecta describe [objetivo…](ADR-0008 del monorepo): el contrato de
cualquier operación de la API sin llamarla. Muestra parámetros, la forma y el
esquema del cuerpo, el esquema de la respuesta, los ejemplos de la
documentación, las notas de uso y los comandos del CLI que la llaman.- Admite la acción (
create_invoice, con los nombres del servidor MCP), el
operationId (createInvoice), la ruta de un comando (invoices create) o
una sección (invoices,delivery-notes); sin objetivo, lista las
secciones. - Con
-jla salida es JSON.--schema body|responseimprime solo el
esquema completo, y--example [n]el cuerpo de ejemplo, listo para
--data.
- Admite la acción (
- La ayuda (
--help) de cada comando que llama a la API termina con la forma
del cuerpo (Cuerpo (--data o stdin): {"content" (obligatorio), "tags"}) y
eldescribede su operación. --search <texto>eninvoices list,estimates list,
delivery-notes list,bills list,payrolls listyrecurring list:
búsqueda aproximada en el texto del documento (título, líneas, notas) y en
el nombre de su contacto, con el mismo criterio que la búsqueda rápida de la
web (sale del contrato de la API).- Informes de FacturaDirecta en
facturadirecta accounting, con las mismas
cifras que la web y calculados en el servidor:accounting results: ingresos, gastos y beneficio por origen, en todos los
planes;--breakdown month|quarter|year(con--total) o
--compare previousPeriod|previousYear(con--difference,--variance).accounting results-documents --category <categoría>: los documentos que
forman una cifra del resumen.accounting profit-loss,accounting balance-sheety
accounting trial-balance: pérdidas y ganancias, balance de situación y
sumas y saldos, para las empresas con el módulo de Contabilidad.
whoamiindica en cada empresa si tiene el módulo de Contabilidad
(accountingModule), con una conexión por empresa.- Adjuntos, como en el MCP:
--summaryindica en facturas, presupuestos y
gastos cuántos ficheros adjuntos tiene cada documento (attachments, solo si
tiene alguno), yfetchlos enumera al final del texto y en
metadata.attachmentscon suurl, que es pública y permanente. - La ayuda de
statements reconcile-newexplica cómo cobrar o pagar una
factura, un gasto o una nómina con el movimiento:{"document": "<id>"},
también entre monedas;amountpara un parcial entre monedas;linessolo
para movimientos sin documento. La deinvoices pay,bills payy
payrolls payrecomienda conciliar el movimiento cuando el cobro o pago sale
del extracto bancario.
Cambiado
products list --searchusa ahora la búsqueda global de la API (título,
referencia y descripciones del producto); el filtro por nombre que antes
hacía--searches ahora--title.journalsolo responde para las empresas con el módulo de Contabilidad (con
una conexión por empresa): sin él, falla conplan_limit_exceededy la pista
facturadirecta accounting results.- Los límites del plan (
plan_limit_exceeded, exit 3) y los informes que
tardan demasiado (report_query_timeout, exit 6) tienen su propio error: ya
no sugierenlogin --scope fullni «revisa los parámetros». - Los errores de validación de la API (
invalid_input) traen endetaillos
mensajes deerrors[]con su campo y, cuando el cuerpo no cumple el esquema
(«Documento con formato incorrecto»), la ruta y el motivo de cada campo
rechazado (hasta 5), como el MCP. Antesdetailsolo traía el mensaje
genérico y un agente no sabía qué corregir. --helpde los subcomandos muestra su descripción antes del uso, como la
ayuda por defecto de Cobra. Antes solo mostraba el uso, y los textos largos
(accounting,auth logout,auth permissions…) no se veían.
Cambiado (BREAKING)
- Los borrados irreversibles piden confirmación: los
deletede facturas,
presupuestos, albaranes, gastos, nóminas, recurrentes, contactos, productos,
métodos de pago, API keys y webhooks, y losattachments delete.- En una terminal preguntan
[s/N]. - En scripts y agentes (sin terminal, o con
-j,-q,--agento--jq)
hace falta--yes. Sin él fallan conconfirmation_required(exit 2) y no
llaman a la API. inbox archiveystatements unreconcileno la piden porque se pueden
deshacer.- La API pública y los SDK no cambian: la confirmación es solo del CLI.
- En una terminal preguntan
Eliminado (BREAKING)
accounting summaryyaccounting accounts. Sumaban el diario en el CLI,
recorriendo hasta 10.000 apuntes, y en las empresas grandes eran lentos e
incompletos.
Corregido
<recurso> attachments list -qdevuelve la lista de adjuntos, como el resto
de listados (imprimía el objeto{"items": …}entero), y admite--ids-only
y--count. Encontrado probando contra el sandbox.describedeupdate_billy de losupdate_*de documentos numerados avisa
de los campos de la lectura que la escritura no admite
(content.accounting,content.booksycontent.importen los gastos, y
content.main.manualTotalsen los documentos numerados), y la skill lo
dice. Reenviar el content de un gasto tal como lo devuelvegetdaba 400.- Ejemplos de la skill y del README: las altas y modificaciones usaban
{"main": {...}}, y el contrato exige
{"content": {"type": "<tipo>", "main": {...}}}. Los envíos por email
van con{"to": [...]}(noemails),invoices substitutioncon
{"contact", "substitutedInvoices"}, los pagos llevanbanky el alta de
webhooks,name. El alta de contactos llevacurrencyyaccounts(vacío =
cliente) y la de productos,sales.account: comprobado contra la API, que
los exige aunque algunos ejemplos de api-docs los omitan. - La skill explica además que
updatesustituye el contenido completo (hay
que partir deget), queinvoices listybills listsolo muestran
borradores con--draft only|all, cómo conciliar condocument, cómo
tratar los adjuntos y quesearchno busca en el texto de los documentos
(para eso,--searchen los listados). Ya no dice quesearchuse la misma
heurística que el MCP, que ahora usa la búsqueda global de la API. - La regla de
updatede la skill dice lo que hace la API (comprobado contra
el sandbox): en contactos, productos y métodos de pago los obligatorios se
envían siempre (no conservan su valor) y no hay líneas nidocNumber; en
los documentos solo se conservan los campos que FacturaDirecta completa por
su cuenta, ydocNumberva tal cual solo en facturas, presupuestos y
albaranes.tagsywebhooks endpoints updateno sustituyen el contenido. describede las operaciones de endpoints y eventos de webhooks y de los
adjuntos de gastos, pedidos, albaranes, presupuestos, nóminas, órdenes de
compra y recurrentes daba la descripción y los ejemplos de otra operación.
Por ejemplo, la delPUTde un endpoint describía el alta, y ahora dice
que es una actualización parcial. Ahora cada una tiene los suyos y su
enlace a la documentación lleva a su sección. Los enlaces con tilde en el
encabezado (23 operaciones) tampoco llevaban a su sección en GitHub.
Migración
- Scripts y agentes que borran: añade
--yesadeleteyattachments delete
después de confirmar el borrado. accounting summary→accounting resultspara ingresos, gastos y
beneficio (--group-by month→--breakdown month), o
accounting trial-balance --account <prefijo>para los totales de una
cuenta o grupo.accounting accounts→accounting trial-balance, que lista las cuentas con
movimientos y su saldo.
v0.13.0
Añadido
- Empresas y permisos por conexión (ADR-0006 del monorepo): tras el login
OAuth, el CLI abre una página de FacturaDirecta para elegir a qué empresas
accede y con qué permisos en cada área, espera a que lo confirmes y guarda
la conexión en el perfil (id, secreto, URL de gestión y nombre; permisos
0600). Cada petición a la API lleva la cabeceraFD-Connection. Con
--deviceo--no-browserla URL solo se imprime. Si cancelas o la
solicitud caduca, el login falla sin guardar nada (el perfil anterior queda
como estaba); si el servidor aún no admite conexiones, avisa y sigue sin
ella. Con--api-keyno hay paso de conexión. login --no-connection: se salta la conexión (acceso a todas tus empresas
con los permisos de tu rol) e inicia sesión con el cliente OAuth
facturadirecta-api, el único con el que la API admite peticiones sin
conexión.facturadirecta auth permissions: abre (o imprime, con--no-browser) la
página para cambiar las empresas y permisos de la conexión del perfil, sin
volver a iniciar sesión. Sin conexión, falla conconnection_requiredy la
pista de login.auth statusyauth profilemuestran la conexión (aplicación, id y URL de
gestión);auth profile, además, los permisos de la conexión en cada
empresa.whoamimuestra la conexión y los permisos de la conexión en cada empresa.
En JSON (whoami --json, la llamada inicial de los agentes) añade
connection(id,clientNameymanageUrl: la de/profileo, si no
la trae, la del perfil guardado; nunca el secreto) y, en cada empresa de
companiesy encompany,permissions(área →read,full…) y
manageUrl. Sin conexión esos campos no aparecen.- Nuevos códigos de error para los 401/403 de la API con conexiones, los
mismos que el MCP (exit 3):connection_permission_insufficienty
company_not_in_connection(pistafacturadirecta auth permissions, con
data.manageUrlydata.companyId),user_role_insufficient,
plan_api_not_available,token_scope_missing(pistalogin --scope full),
connection_requiredyconnection_revoked(pistalogin). Con estos
códigos, el texto para humanos esHTTP 403: <mensaje>en vez del cuerpo
JSON. Sincode, todo sigue igual. - Variables de entorno para probar contra otro entorno:
FACTURADIRECTA_SERVER(servidor de la API que el login guarda en el
perfil) yFACTURADIRECTA_OAUTH_CLIENT_ID(fuerza el cliente OAuth del
login; por defectofacturadirecta-cliy, con--no-connection,
facturadirecta-api). - Comando oculto
facturadirecta __surface: imprime en JSON el árbol completo
de comandos visibles (ruta, padre, textos, uso, subcomandos y flags propias),
las flags globales y los grupos de la ayuda raíz.make surface-jsonlo
escribe endist/commands.json. - Cada release adjunta ese JSON como asset
commands.jsonen
facturadirecta/cli, con URL estable
https://github.com/facturadirecta/cli/releases/latest/download/commands.json.
La web de desarrolladores genera con él la referencia del CLI.
Cambiado
- El login OAuth usa por defecto el cliente propio del CLI,
facturadirecta-cli(antesfacturadirecta-api, compartido con Zapier y
las integraciones): con él, la API exige la conexión (connection_required
sin ella). Necesita ese cliente en el realm de Keycloak (tarea 6 de
tools/mcp-connect-clients.shdel repo keycloak) y la API con conexiones.
Los perfiles existentes siguen funcionando confacturadirecta-apihasta el
siguiente login.--no-connectionusafacturadirecta-api. logoutrevoca la conexión del perfil en FacturaDirecta antes de borrarlo;
si no puede, avisa y cierra la sesión igualmente. Volver a iniciar sesión
sobre un perfil con otra conexión también la revoca.- El perfil guarda el cliente OAuth del login y el token se renueva siempre
con él (los perfiles anteriores, confacturadirecta-api).
v0.12.2
Corregido
- Las URLs de
--summary,--url,searchyfetchapuntan a la
aplicación web (https://3.facturadirecta.com/…): son elwebUrlque
devuelve la API. Antes el CLI las componía sobre el servidor del perfil
(app.facturadirecta.com), donde esas rutas daban 404. Si la API no
devuelvewebUrl, los resúmenes,searchyfetchomitenurly--url
termina con un errorupstream_error.
Cambiado
- Textos de ayuda de las flags de listados corregidos desde el contrato de la
API:--has-tagsdecía lo contrario de lo que hace (contruedevuelve
solo los elementos que tienen al menos una etiqueta), y se corrigen erratas
en las fechas (--min-creation-datey similares) y en--max-total.
v0.12.1
Corregido
- Las búsquedas y filtros con espacios (
contacts list --search "Acme SL")
fallaban con 400: el SDK Go codificaba el espacio como+, que la API
rechaza ("must be url encoded"); ahora va como%20(RFC 3986). facturadirecta whoamiyauth profilefallaban con un perfil de API key
(HTTP 401: Es necesaria identificación para usar este servicio): llamaban
aGET /profile, que solo admite OAuth, y las API keys son por empresa y
no tienen usuario. Ahora detectan el perfilapikeyy, sin pasar por
/profile, devuelven la empresa de la clave (la de
login --api-key --company;--companyyFACTURADIRECTA_COMPANYsiguen
mandando): en JSON conauthType: "apikey",companyycompanies(solo
esa), y en la tabla como "Perfil con API key: empresa ". Comprueban
además que la clave es válida para esa empresa con
GET /{companyId}/apiKeyInfoe incluyen sus scopes (scopesen JSON); si
la API responde 401/403, el error (auth_required) indica que la API key
no es válida o ha sido revocada y cómo volver a iniciar sesión. Un perfil
de API key sin empresa ya no consulta/profileen ningún comando: pide
--companyo un nuevo login.- Un 401 de la API (sesión caducada, API key no válida o revocada) se
clasificaba comoinsufficient_scopey sugeríafacturadirecta login --scope full, que no lo arregla. Ahora esauth_required(exit 3) con el
mensaje "La API no ha aceptado las credenciales (HTTP 401)…" y la pista
facturadirecta login. El 403 sigue siendoinsufficient_scopecon la
pista--scope full. - Las pistas de login (
auth_required,readonlyeinsufficient_scope)
añaden--profile <nombre>cuando el perfil activo no es el por defecto,
para que el comando sugerido repare la sesión que ha fallado y no cree
otra. - Cuando el refresh token OAuth ha caducado o ha sido revocado, el CLI
devolvía un error genérico (internal, exit 1). Ahora esauth_required
(exit 3) con la respuesta del servidor de identidad endetaily la pista
de login; si lo que falla es la red al renovar, esnetwork_error. El
error "No hay sesión activa" del cliente HTTP también esauth_required. --profile <nombre>(oFACTURADIRECTA_PROFILE) con un perfil que no
existe devolvía un error genérico. Ahora esauth_requiredcon la pista
facturadirecta login --profile <nombre>y los perfiles disponibles en
data.profiles.
v0.12.0
Añadido
facturadirecta login --device: inicio de sesión por dispositivo (OAuth 2.0
Device Authorization Grant, RFC 8628) para máquinas sin navegador (SSH,
contenedores, agentes): el CLI muestra una URL y un código para autorizar
desde cualquier dispositivo. Requiere el grant activado en el cliente
facturadirecta-apide Keycloak.login --no-browser(solo imprime la URL) ylogin --port(fija el puerto
del callback). VariableFACTURADIRECTA_KEYCLOAK_URLpara apuntar el login
a otro Keycloak (desarrollo).statements unreconcile --delete-transaction: el parámetro del contrato
que faltaba (borrar también el asiento al desconciliar).facturadirecta search <texto>yfacturadirecta fetch <id>: la búsqueda
combinada y el detalle legible que ofrecen las toolssearch/fetchdel
MCP, con los mismos ids (tipo:empresa:id) y URLs.searchcombina
contactos, productos, facturas y presupuestos por número y los últimos
documentos de los contactos encontrados;--typeacota los tipos. Sin
empresa fijada y con varias empresas busca en hasta 5.- Errores clasificados. En modo agente (
-j,-q,--agent,--jq) los
errores van a stderr como una línea JSON concode(los del MCP:
not_found,insufficient_scope,invalid_input,company_required,
upstream_error; y los del CLI:usage,auth_required,readonly,
network_error),message,status,detail,hintydata; el
proceso sale con un código por clase (2 uso/entrada, 3 sesión/permisos,
4 no encontrado, 5 empresa, 6 API/red). El texto para humanos no cambia. facturadirecta accounting summaryyaccounting accounts: agregados del
diario contable con la misma forma quesummarize_accountingy
list_accountsdel MCP.summarydevuelve debe, haber y saldo por cuenta,
mes o cuenta+mes, más ingresos (grupo 7), gastos (grupo 6) y resultado;
accountslista las cuentas con movimientos y su saldo (la API no expone
el plan de cuentas). Paginan el diario hasta 10.000 apuntes y avisan si el
periodo tiene más.facturadirecta whoami: perfil, usuario, modo de acceso, la empresa que
usarán los comandos (y de dónde sale) y las empresas disponibles en una sola
llamada; con--jsondevuelve un objeto compacto pensado para agentes.--summaryenlistygetde facturas, presupuestos, gastos, contactos y
productos: resumen compacto por elemento (id, número, fecha, contacto,
totales, estado, saldo pendiente y url) en las salidas JSON. En facturas y
gastos piderelated=state,balanceautomáticamente;pendingAmountes
positivo cuando queda importe por cobrar o pagar.--urlenget: imprime solo la URL del elemento en la web de FacturaDirecta.- Variable de entorno
FACTURADIRECTA_COMPANY: fija la empresa para una
sesión de shell sin tocar el perfil. journal --id: apuntes originados por un documento concreto (asiento,
factura, gasto, nómina o remesa). No confundir con--document, que filtra
por el documento al que se imputan.statements list --matched-document: extractos conciliados con un asiento.settings seriesadmiteclientOrderypurchaseOrder.
Cambiado
- El callback OAuth del login escucha en un puerto loopback libre elegido por
el sistema (127.0.0.1:<puerto>, RFC 8252) en vez del 31337 fijo: dos
logins a la vez o un puerto ocupado ya no hacen fallar el inicio de sesión. - Los scopes que pide el login salen del contrato de la API (SDK) en vez de
una lista escrita a mano: incluye ahoraclientOrders,customFieldsy
purchaseOrders. - Las flags de query de todos los listados y consultas se generan desde el
contrato de la API (internal/commands/flags.gen.go, emitido por el
generador del monorepo desde la IR) en vez de escribirse a mano: nombre
kebab-case, tipo y ayuda (primera frase de la documentación de la API más
los valores admitidos). Los nombres de las flags no cambian; sí cambian
los textos de--help. La paridad con el contrato la comprueba un test
(internal/cli/flags_test.go) que sustituye ascripts/check-flags.py. - Los errores se imprimen una sola vez: sin el "Error:" duplicado de cobra ni
el volcado delusagecompleto tras cada fallo (en errores de uso se
sugiere--help). - Resolución de empresa determinista:
--company>FACTURADIRECTA_COMPANY>
empresa fijada en el perfil > la única empresa del usuario (se guarda en el
perfil). Con varias empresas y ninguna fijada, el error lista las
disponibles en vez de exigirauth use-company. - El skill para agentes pasa a llamarse
facturadirecta-cliy se instala en
<skills>/facturadirecta-cli, para no pisar el skillfacturadirectadel
MCP remoto (ni ser pisado por él).setupretira la copia antigua del CLI
si la encuentra. El skill recomienda empezar conwhoami --jsony usar
--summaryen los listados, y corrigejournal list(el comando es
journal).