Skip to Content

Novedades

Notas de versión de acp2md, de más reciente a más antigua. El comportamiento de conversión proviene del motor ADF compartido de Climakers, así que la mayoría de los cambios de salida se aplican también a acs2md.


v1.0.12

Restaurar una página desde una copia de seguridad

page restore devuelve una página a Confluence desde un archivo de page get (--file, con --attachments-dir) o desde una página de una copia de seguridad de espacio de acs2md (--backup-dir y --page-id). A una página que sigue vigente en el espacio se le restaura la versión respaldada, conservando su ID y su historial, o se le escribe el cuerpo respaldado como una versión nueva; una página en la papelera, archivada o eliminada se crea de nuevo bajo su padre respaldado. Se añaden los adjuntos, las etiquetas y las propiedades de contenido que faltan, y las imágenes de un cuerpo ADF pasan a apuntar a los archivos restaurados. Una propiedad que la página tiene con otro valor se conserva, porque las aplicaciones guardan ahí su estado; --overwrite-properties la sustituye. El mensaje de la versión restaurada nombra la fecha de la copia de seguridad, nunca una ruta local.

El plan se muestra y se confirma primero (--yes en scripts, --dry-run para solo mirar). Es el primer comando de acp2md que escribe en Confluence, y nunca elimina, envía a la papelera, archiva ni mueve nada. page check compara antes una página respaldada con Confluence: su estado, versión y cuerpo, y los adjuntos y etiquetas que ya no tiene. Consulta Restaurar páginas.

page get guarda los adjuntos

--attachments-dir <dir> descarga los adjuntos de la página en <dir>/<page-id>/ y los describe: dentro del JSON de la página con atlas_doc_format, en <dir>/<page-id>.attachments.json con storage. Disponible en by-id, by-title y by-url, de modo que una página puede respaldarse y restaurarse con sus archivos. Consulta Guardar adjuntos.

Cada petición tiene un plazo

El nuevo http.client.request_timeout (por defecto 10m, 0 lo desactiva) limita una petición desde que se envía hasta que se lee toda la respuesta, incluidos sus reintentos y las esperas de Retry-After. Antes, una conexión bloqueada dejaba colgada la ejecución hasta Ctrl-C. Los archivos de configuración existentes no tienen la clave y reciben el valor por defecto; doctor muestra el valor en una nueva fila HTTP request timeout. El mensaje “Timed out waiting for the Confluence API” nombra ahora este ajuste en lugar de http.client.max_timeout, que limita el backoff de los reintentos y no termina una petición lenta. Consulta Cada petición tiene un plazo.

Correcciones

  • Los comandos ya no se quedan colgados cuando stdin queda abierta. Todos los comandos que reciben un ID, un título o una URL de página leían la entrada estándar hasta el final siempre que no fuera un terminal, incluso con el valor ya en la línea de comandos. Desde un runner de CI, una sesión ssh o una herramienta que mantiene stdin abierta, el comando esperaba para siempre. Ahora stdin solo se lee cuando falta el argumento, así que echo 123456 | acp2md page convert by-id sigue funcionando.
  • Volver a activar con una clave renovada funciona. Una suscripción renovada conserva su clave, pero license activate --license-key <la misma clave> la rechazaba con “license has expired” una vez vista la caducidad en local. Ahora el comando pregunta a la tienda y actualiza la licencia instalada cuando la tienda informa de que la clave vuelve a estar activa.
  • --force hace lo que prometía su ayuda con una clave. license activate --license-key <clave-nueva> --force sustituye una licencia activa, liberando antes su puesto; antes, el flag solo se aplicaba a los archivos de licencia. Consulta Volver a ejecutar activate.
  • Los árboles de comandos se regeneran desde los binarios. La referencia de acp2md se había quedado atrás y le faltaban los flags de page convert, page count y page properties; el listado de tree --short de este manual muestra ahora también page check y page restore.

Por dentro

Las escrituras pasan por un cliente HTTP separado que respeta Retry-After solo en 429 y nunca reintenta a ciegas, así que una creación de página cuya respuesta se perdió se busca en lugar de enviarse dos veces. El estado de sincronización y las descargas de adjuntos se publican a través de un archivo temporal y un renombrado, así que una descarga que falla a medias no deja nada atrás. Compilado con Go 1.27.3.


v1.0.10

Saber cuándo hay algo que instalar

acp2md doctor informa de la versión más reciente disponible para ti en una nueva fila Latest version, junto con el comando que la instala; la comprobación nunca hace fallar el diagnóstico y dice “could not check” sin conexión. Después de un comando ordinario, acp2md también consulta el servicio de actualizaciones como máximo una vez al día, espera como máximo dos segundos e imprime una sola línea en stderr cuando existe una versión más reciente. El aviso nunca aparece en CI, bajo sudo, cuando stderr no es un terminal, ni después de update, license, doctor y config. Desactívalo con acp2md config set update.notice false. Consulta El aviso diario de nueva versión.

acp2md update también sigue funcionando cuando se alcanza el límite diario de descargas de la tienda —cada archivo puede descargarse diez veces al día— y, a partir de ahí, obtiene la misma versión desde el almacenamiento de versiones propio de Climakers, una vez al día por instalación.

La activación es más estable en Linux

Los archivos de licencia se cifran contra un identificador de máquina, y en Linux ese identificador sobrevive ahora a las actualizaciones del kernel y del microcódigo y a los cambios de tamaño de las VM. Las licencias activadas antes de esta versión siguen funcionando: una licencia de suscripción pasa al nuevo identificador la primera vez que se abre, y una licencia local firmada conserva el identificador para el que se emitió. No hace falta volver a activar nada. macOS no se ve afectado.

Correcciones

  • acp2md update ve una versión nueva de inmediato. Justo después de una publicación, update podía informar de la versión anterior durante varios minutos porque el servicio de actualizaciones respondía desde una copia en caché. Instalar, y update --check --force, consultan ahora el servicio directamente, así que una versión se ofrece en menos de un minuto desde su publicación; un update --check sin más puede tardar hasta dos minutos.

v1.0.9

Correcciones

  • license activate --license-key <archivo> dice qué flag recibe un archivo. Pasar un archivo de licencia a --license-key respondía “invalid license key format: expected UUID v4”; ahora explica que un archivo de licencia se activa con --license-file e imprime el comando exacto.

v1.0.8

Nada de lo que usas cambia: el motor de actualización pasó a un módulo compartido de Climakers, que ajat también usa ahora, y update se comporta exactamente igual que antes.


v1.0.7

Las licencias sin conexión también se actualizan

Una licencia local emitida por licensegen con una clave de firma lleva una firma que el servicio de actualizaciones verifica por sí mismo, así que los clientes sin conexión reciben acp2md update como todos los demás; sus descargas provienen del almacenamiento de versiones de Climakers en lugar de la tienda. Las licencias locales emitidas antes de que existiera la firma se rechazan con “this local license is not signed” y una pista para activar un archivo reemitido. Consulta Tu suscripción y las versiones anteriores.


v1.0.6

Actualizaciones desde la propia herramienta

acp2md update instala la versión más reciente que incluye tu licencia: consulta en Climakers si hay una versión más reciente, la descarga, verifica su suma SHA-256 y reemplaza el binario en ejecución. En macOS instala el paquete firmado y notarizado y se ejecuta como sudo acp2md update; en Linux reemplaza el binario en su sitio y nunca usa sudo. --check informa sin cambiar nada, --version v1.1.0 instala una versión concreta (que es también la forma de volver atrás), --yes omite la confirmación y es obligatorio en CI, y --format json es para scripts. Cuando termina una suscripción, las versiones publicadas antes de esa fecha siguen siendo instalables. El comando no necesita credenciales de Confluence y no cuenta para el límite de comandos de la licencia. Consulta Actualizar acp2md.

La salida de --format json cambió en dos aspectos

La salida JSON la produce ahora encoding/json/v2 de Go. Dos diferencias visibles, ambas deliberadas:

  • una lista o un mapa vacíos se imprimen como [] / {} en lugar de null, así que una página sin etiquetas es "labels": [] y no "labels": null;
  • <, > y & dentro de las cadenas ya no se escapan, así que un título como Q&A <draft> se lee tal como está escrito.

El orden de las claves, la indentación y el salto de línea final no cambian, y los archivos de estado de sincronización siguen siendo legibles por versiones anteriores. Los scripts que comprueban null deberían comprobar una lista vacía.

Notas de plataforma

  • Se requiere macOS 13 (Ventura) o posterior. La cadena de herramientas de Go con la que se compila esta versión dejó de admitir versiones anteriores de macOS.
  • Se respetan SSL_CERT_FILE y SSL_CERT_DIR en macOS. Cuando alguna está definida, las raíces de certificados se cargan desde esas rutas en lugar del almacén de la plataforma, el comportamiento que Linux siempre tuvo. Las configuraciones de proxy corporativo que definen estas variables para otras herramientas verán que aquí también se aplican; GODEBUG=x509sslcertoverrideplatform=0 restaura el comportamiento anterior.

v1.0.5

Esta versión cambió la salida Markdown por defecto en las páginas que contienen paneles y para quien use --include-metadata. Las dos acciones de abajo no hacen nada si nunca escribiste el ajuste correspondiente.

Acción: revisa image.max_size_bytes

El valor por defecto bajó a 2 MB, pero una configuración escrita antes de esta versión casi con seguridad fija el antiguo 10485760, lo bastante permisivo como para incrustar un fondo de página y producir un archivo que ningún editor maquetará. La configuración gana a los valores por defecto, así que sigue imponiéndose:

acp2md config get image.max_size_bytes # 10485760 significa que el valor antiguo está fijado acp2md config set image.max_size_bytes 2097152

acs2md lee su propia configuración, así que ejecuta el mismo par allí si lo usas.

El front matter lleva nombres visibles y las menciones enlazan a los perfiles de las personas. Cuando una exportación se publica fuera de la organización, --resolve-users=false conserva los IDs de cuenta opacos.

Se respeta Retry-After

Cuando Confluence responde a una petición limitada con 429 o 503 e indica un retardo, el cliente espera ahora exactamente ese tiempo en lugar de recurrir a una planificación adivinada localmente. El servidor sabe cuánto dura su ventana; el cliente no.

Un retardo superior a 60 segundos se muestra en vez de esperarse, así que un comando nunca parece colgado, y la espera es interrumpible.

Los valores por defecto del backoff cambiaron, y actualizar no llega a una instalación existente. Subieron de 10ms/100ms a 500ms/30s, pero un archivo de configuración materializa todos los valores por defecto al crearse y la configuración gana a los valores por defecto. Una instalación antigua conserva un presupuesto total de 70 ms repartido en tres intentos, incapaz de sobrevivir a una ventana real de limitación. Ejecuta acp2md doctor para comprobarlo y consulta Reintentos y límite de peticiones.

Las imágenes se pueden escribir como archivos sidecar

--image-sidecars guarda cada imagen en attachments/<page-id>/ junto al Markdown y la enlaza de forma relativa, en lugar de incrustar una URI de datos en base64. La exportación sigue siendo autónoma en ambos casos: lo que cambia es la longitud de línea.

En una página real: 1.440.451 B y una línea de 244.311 caracteres en base64, frente a 12.100 B y 379 caracteres con sidecars. En un espacio completo además se deduplica: una imagen reutilizada en diez páginas se guarda una sola vez.

--obsidian lo activa, porque el base64 era lo último de ese preajuste que no se renderizaba en Obsidian.

Salida para Obsidian

Un preajuste completo — callouts, anclajes de encabezado que Obsidian resuelve y archivos sidecar de imagen — además de --wikilinks, --inline-tags, --panel-style y --media-dimensions. Consulta Bóvedas de Obsidian.

Los paneles se renderizan como alerts de GitHub

> [!NOTE], > [!TIP], > [!WARNING] y > [!CAUTION] sustituyen a la cita con emoji anterior. Los alerts se renderizan tanto en GitHub como en Obsidian. Los tipos de panel sin equivalente conservan la forma con emoji. --panel-style=emoji restaura la salida antigua.

El front matter es YAML válido

--include-metadata emite ahora YAML determinista y correctamente entrecomillado, que Obsidian lee como Properties y que Jekyll, Hugo y Pandoc interpretan:

AntesAhora
Title, AuthorID, CreatedAt, ID, LastOwnerID, OwnerID, ParentID, ParentType, Position, SpaceID, Status, SubType, VersionAuthorID, VersionCreatedAt, VersionMessage, VersionMinorEdit, VersionNumbertitle, tags, author, created, updated, source, space, status, version, id, parent_id, owner_id

Las fechas son YYYY-MM-DD, tags procede de las labels de Confluence de la página, source es la URL de navegador y los campos vacíos se omiten. Los campos eliminados eran contabilidad interna de Confluence que ningún consumidor de Markdown usaba.

Las labels se recuperan automáticamente

Con el front matter activado, tags se rellena sin pasar --include-labels. En page convert esto viaja con la petición de página existente, sin coste adicional.

Los enlaces de encabezado se resuelven en el renderizador para el que exportas

La tabla de contenidos emitía anclajes de tipo slug al estilo de GitHub sin importar el destino. --panel-style=obsidian (y por tanto --obsidian) emite ahora anclajes que Obsidian resuelve.

Cada comando informa de cuánto ha tardado

⏱️ Converted in 559ms

La cifra cubre el comando completo, incluidas las llamadas a la API y las descargas de imágenes. Se imprime en stderr, nunca en stdout, para que acp2md page convert by-id 123 > page.md y los pipelines sigan limpios.

Un segundo Ctrl+C fuerza la salida

La primera interrupción cancela de forma limpia y deja que se repliegue el trabajo en vuelo. Antes, cualquier Ctrl+C adicional se descartaba y una ejecución que parecía atascada no se podía detener.

Correcciones

  • --debug no producía salida alguna. Fijaba el nivel de log pero dejaba el destino en su valor por defecto, que lo descarta todo. Ahora escribe en stderr salvo que --log-file indique otra cosa.
  • Un log.level, log.format o log.file inválido bloqueaba todos los comandos, incluidos los comandos config que lo reparan. Ahora recurren a unos ajustes de log que funcionan durante esa ejecución e indican qué clave cambiar.
  • Una opción global colocada antes de un comando exento hacía que este exigiera licencia o validara la configuración. acp2md --log-file x.log doctor tomaba --log-file como nombre de comando, así que doctor — el comando que se ejecuta para diagnosticar problemas de licencia — se negaba a arrancar en una máquina sin licencia.
  • Un http.client.proxy inválido ahora es un error, no un aviso seguido de continuar. Enviar el tráfico directo en silencio cuando se pidió enrutarlo es, en una red corporativa, motivo para detenerse.

Consulta también

Last updated on