# Referencia de la CLI de AfterPack

Cómo invocar npx afterpack@latest: una ruta opcional, cada clave de configuración como flag, los subcomandos verify, restore y audit y el contrato completo de códigos de salida.

Source: https://www.afterpack.dev/es/docs/cli

`npx afterpack@latest` ofusca un directorio de build. Úsalo cuando no exista un plugin para tu bundler, o en [CI](https://www.afterpack.dev/es/docs/builds). Si existe un plugin para tu framework, instala `@afterpack/<fw>` en su lugar: tu build habitual emitirá entonces salida ofuscada sin ningún paso adicional. Consulta [Frameworks](https://www.afterpack.dev/es/docs/frameworks).

Esta página cubre el [argumento](#usage), los [ejemplos](#examples), [qué hace una ejecución](#what-a-run-does), [`verify`](#afterpack-verify-dir), [`restore`](#afterpack-restore-dir), [`audit`](#afterpack-audit-url), la [salida legible por máquina](#machine-readable-output) y los [códigos de salida](#exit-codes). Cada opción se define una sola vez, en [Configuración](https://www.afterpack.dev/es/docs/config).

## Uso

```
afterpack [path] [--<key>=<value> ...] [-h | --help] [-v | --version]
afterpack verify [dir]
afterpack restore [dir]
afterpack audit <url>
```

```bash
npx afterpack@latest
```

La ruta acepta una de dos cosas:

- un directorio, recorrido de forma recursiva en busca de cada `.js`, `.mjs` y `.cjs`, o
- un único archivo `.js`, `.mjs` o `.cjs`, ofuscado por sí solo.

Si lo ejecutas sin ruta, `afterpack` detecta la salida de tu build: el directorio en el que escribe por convención el bundler declarado en tu `package.json` (Next.js → `.next/`, Nuxt → `.output/`, SvelteKit → `build/`, Electron → `out/`, cualquier otro bundler compatible → `dist/`) cuando ese directorio existe; si no, el más reciente entre `dist/`, `build/`, `out/`, `.output/` y `.next/`. Nunca lee el archivo de configuración de tu bundler, así que un directorio de salida personalizado no se detecta: pasa la ruta tú mismo cuando tengas uno. Imprime qué encontró y qué va a hacer, y después se ejecuta; en CI nunca pide confirmación. Cuando no encuentra nada, imprime la ayuda de inicio rápido y sale con `1`. El comando también lee tu bundler desde `package.json` e imprime al final de la ejecución una línea que sugiere el [plugin correspondiente](https://www.afterpack.dev/es/docs/frameworks).

Apúntalo a la salida de tu bundler, no a tu código fuente. La mayoría de los bundlers ([Vite](https://www.afterpack.dev/es/docs/frameworks/vite), [Rollup](https://www.afterpack.dev/es/docs/frameworks/rollup), [esbuild](https://www.afterpack.dev/es/docs/frameworks/esbuild), [webpack](https://www.afterpack.dev/es/docs/frameworks/webpack), [Astro](https://www.afterpack.dev/es/docs/frameworks/astro), [Parcel](https://www.afterpack.dev/es/docs/frameworks/parcel)) escriben en `dist/`. [Next.js](https://www.afterpack.dev/es/docs/frameworks/nextjs) escribe en `.next/` y [Nuxt](https://www.afterpack.dev/es/docs/frameworks/nuxt) en `.output/`.

## Ejemplos

```bash
npx afterpack@latest                                        # detects the build output, light default
npx afterpack@latest dist/                                  # a directory you choose
npx afterpack@latest dist/ --preset=hard                    # heavier posture
npx afterpack@latest .next/ --seed=git                      # reproducible output, pinned to the commit
npx afterpack@latest build/widget.js                        # one file
npx afterpack@latest dist/ --diagnostics.level=all          # every diagnostic, not the rolled-up summary
AFTERPACK_complexity=40 npx afterpack@latest dist/           # any flag also works as an env var
```

## Qué hace una ejecución

1. Recopila el JavaScript en `<path>`. Recorre de forma recursiva cuando la ruta es un directorio, omite sus propias [copias `.backup.<hash>`](#files) y omite `node_modules/` a menos que lo incluyas con [`--paths.include='**/node_modules/**'`](https://www.afterpack.dev/es/docs/config#paths-include). Si no recopila nada, el build falla.
2. Mantiene `.afterpack/` fuera de git con un `.gitignore` dentro de él, que se escribe la primera vez que hace falta. Tu propio `.gitignore` nunca se edita.
3. Ofusca en el sitio cada archivo recopilado, con el [preset](https://www.afterpack.dev/es/docs/config#preset) solicitado, o con [`--complexity`](https://www.afterpack.dev/es/docs/config#complexity) cuando lo fijas de forma explícita. En un build de Next.js, Angular, Vite o webpack también renombra cada archivo con hash de contenido para que coincida con sus bytes ofuscados y reescribe cada referencia a él; en cualquier otra salida los nombres quedan tal como los escribió tu bundler. Consulta [Nombres de archivo con hash de contenido](#content-hashed-file-names).
4. Escribe los artefactos que los flags permiten y, siempre, el [recibo de protección](#files). Cuando está activado (por defecto, si se encontró un source map y el build no se ejecuta en CI), el [Protection Map](https://www.afterpack.dev/es/docs/protection-map) combinado se guarda en `.afterpack/protectionMap.html`, ignorado por git y nunca servido, porque incrusta tu código fuente original. Un source map o una copia de seguridad contiene tu código fuente completo. Nunca despliegues ninguno de los dos. Si alguno queda bajo un segmento de ruta servido, la CLI avisa una vez.
5. Imprime los [diagnósticos](https://www.afterpack.dev/es/docs/diagnostics) y, después, la sugerencia de bundler si encontró uno.

> **Las ejecuciones no son idempotentes**
>
> El comando sobrescribe la salida de tu build en el sitio y no conserva ninguna copia desde la que volver a ofuscar. Compila y luego ejecútalo una sola vez. En [CI](https://www.afterpack.dev/es/docs/builds) ese orden es automático.

### No lo ejecutes dos veces sobre la misma salida

AfterPack se niega a ofuscar un archivo que ya contiene su propia salida ofuscada de una ejecución anterior: compara los archivos recopilados con el [recibo de protección](#afterpack-verify-dir) por hash de contenido y hace fallar el build con `DIAG_ALREADY_OBFUSCATED`, sea cual sea el directorio desde el que lo ejecutes, en lugar de ofuscar código ya ofuscado. Una copia que un framework hizo de una salida protegida, como el `build/` de SvelteKit, se rechaza del mismo modo. Primero vuelve a compilar desde el código fuente: borra el directorio de salida o ejecuta el paso de limpieza de tu bundler.

### Nombres de archivo con hash de contenido

Los bundlers nombran cada chunk según un hash de su contenido, como `index-4f9a2c1e.js`, para que un servidor pueda guardarlo en caché durante un año con `Cache-Control: immutable`. La ofuscación cambia los bytes, así que en los builds de abajo la ejecución da a cada archivo con hash de contenido un hash nuevo en su nombre y reescribe cada referencia a él en el HTML, los manifiestos y los demás chunks. Un nombre nunca apunta a bytes distintos, así que un navegador, una CDN o un service worker nunca sirve una copia obsoleta bajo un nombre reutilizado. El hash nuevo se obtiene del original más la semilla, la versión del motor y tu configuración, igual que un [plugin](https://www.afterpack.dev/es/docs/frameworks) nombra sus archivos; [Nombres de archivo y caché](https://www.afterpack.dev/es/docs/builds#file-names-and-caching) explica qué significa la semilla para tu caché.

| Build | Apunta la CLI a | Qué renombra la ejecución |
|---|---|---|
| [Next.js](https://www.afterpack.dev/es/docs/frameworks/nextjs), con webpack o Turbopack | `.next/`, `.next/static/` o `.next/static/chunks/`; `out/` para una exportación estática | Los chunks bajo `static/chunks/` |
| Application builder de [Angular](https://www.afterpack.dev/es/docs/frameworks/angular) | `dist/<app>/browser/` o `dist/<app>/` | Cada archivo con hash. La ejecución también recalcula los atributos `integrity` y la tabla de hashes `ngsw.json` del service worker |
| [Vite](https://www.afterpack.dev/es/docs/frameworks/vite) | Un directorio con un `index.html` o un `.vite/manifest.json` | Los scripts y hojas de estilo `name-<hash>` de `assets/`, o de las carpetas que nombra el manifiesto |
| [webpack](https://www.afterpack.dev/es/docs/frameworks/webpack) | Un directorio cuyo runtime de webpack carga los chunks | Los archivos con un hash de contenido hexadecimal en su nombre |

Los nombres con hash de contenido quedan tal como los escribió tu bundler, y la ejecución imprime un único aviso, cuando:

- la ruta es un solo archivo, o la salida viene de cualquier otro bundler;
- no se puede identificar el bundler de un build de Next.js;
- en un build de Vite o webpack, un archivo con hash no está referenciado desde dentro del directorio de build, dos hashes no se pueden distinguir, o una carpeta junto al directorio de build, como un bundle de servidor, `.svelte-kit/` o `.output/`, nombra los archivos con hash o es demasiado grande para comprobarla;
- un manifiesto de precaché, como el de Workbox, lista los archivos por revisión.

Para una caché de larga duración en un build así, usa el [plugin](https://www.afterpack.dev/es/docs/frameworks) de tu framework, o fija una [`--seed`](https://www.afterpack.dev/es/docs/config#seed) constante.

Un build de servidor de Angular cuyo `angular-app-manifest.mjs` incrusta hashes de assets se rechaza con salida `1`, y la salida queda tal como la escribió el builder. Ofusca la salida de navegador de un build sin SSR.

## Flags

Cada clave de configuración es un flag: `--<key>=<value>`, por ejemplo `--complexity=40` o `--identifiers.reserved=Hls,Foo` para una lista. Un flag booleano se escribe sin valor para `true` (`--build.backup`) y `=false` la desactiva (`--protectionMap.enabled=false`). `-h, --help` y `-v, --version` imprimen y salen con `0`.

Cada clave escalar o de lista de la [referencia de opciones](https://www.afterpack.dev/es/docs/config) funciona como flag de esta forma. Los valores estructurados van en `afterpack.json`. Las variables de entorno siguen los mismos nombres con los puntos convertidos en guiones bajos, consulta [Configuración](https://www.afterpack.dev/es/docs/config); por ejemplo, [`AFTERPACK_key`](https://www.afterpack.dev/es/docs/config#key), [`AFTERPACK_preset`](https://www.afterpack.dev/es/docs/config#preset) y [`AFTERPACK_telemetry_enabled`](https://www.afterpack.dev/es/docs/config#telemetry-enabled).

## Archivos

| Ruta | Función |
|---|---|
| `afterpack.json` | El archivo de configuración. AfterPack sube desde el directorio de trabajo hasta la coincidencia más cercana. Contiene toda la [configuración del motor](https://www.afterpack.dev/es/docs/config#example-afterpackjson): opciones de build, [`key`](https://www.afterpack.dev/es/docs/config#key), todo. |
| `.afterpack/receipts/<build dir>.json` | El recibo de protección de un directorio de build, por ejemplo `.afterpack/receipts/dist.json` o `.afterpack/receipts/.next.json`. Una ruta larga o poco habitual recibe un nombre abreviado con un hash. Registra cada archivo de salida con el hash de los bytes escritos, la versión del motor y la semilla. [`afterpack verify`](#afterpack-verify-dir) vuelve a calcular los hashes contra él, y gracias a él se rechaza una ejecución posterior sobre la misma salida sin recompilar. |
| `.afterpack/protectionMap.html` | El [Protection Map](https://www.afterpack.dev/es/docs/protection-map) combinado. Ignorado por git automáticamente. Incrusta tu código fuente original. Nunca lo confirmes en git ni lo sirvas. |
| `.afterpack/backups/<build dir>/` | Tus originales de un directorio de build, byte a byte, por ejemplo `.afterpack/backups/dist/`, con un manifiesto de cada archivo que la ejecución creó, modificó, renombró o eliminó. Cada directorio de build tiene su propia copia de seguridad y su propio [bloqueo](#parallel-runs-and-locks), así que los builds de distintas apps de un mismo repositorio nunca comparten una. Se escribe en cada ejecución ([`--build.backup=false`](https://www.afterpack.dev/es/docs/config#build-backup) lo desactiva), y [`afterpack restore`](#afterpack-restore-dir) lo lee para deshacer la ejecución. La ejecución imprime su ruta al terminar. Es tu código fuente. Nunca lo confirmes en git ni lo despliegues. |
| `<file>.js.map` | El source map emitido, cuando [`sourceMap.enabled`](https://www.afterpack.dev/es/docs/config#sourceMap-enabled) está activado. Desactivado por defecto: una ejecución es de [producción](https://www.afterpack.dev/es/docs/config#build-mode) salvo que diga que es de desarrollo, y una ejecución de producción también elimina los source maps que escribió tu bundler, incluidos los de CSS. Un source map publicado lleva la salida directamente de vuelta a tu código fuente. |

`.afterpack/` guarda los recibos, el Protection Map y las copias de seguridad. AfterPack lo encuentra a partir del directorio de build, sea cual sea el directorio desde el que ejecutes. Sube hasta la carpeta más cercana que contenga un lockfile (`package-lock.json`, `npm-shrinkwrap.json`, `pnpm-lock.yaml`, `yarn.lock`, `bun.lock` o `bun.lockb`), `afterpack.json` o `.git`. Si no la hay, usa la carpeta más cercana con un `package.json`, y si tampoco la hay, se coloca junto al directorio de build. Esa carpeta es la raíz de tu proyecto en estas páginas. `.afterpack/` nunca está dentro de la salida del build.

Una ejecución falla, sin reescribir nada, cuando encuentra una carpeta `.afterpack/` dentro de la salida del build (`DIAG_AFTERPACK_DIR_IN_OUTPUT`: borra esa carpeta y vuelve a compilar) o cuando no puede escribir el recibo (`DIAG_RECEIPT_UNWRITABLE`). Un `.afterpack-protection.json` que una versión anterior dejó en la salida se elimina en la siguiente ejecución.

## `afterpack verify [dir]`

La puerta de despliegue. Cada build protegido escribe un recibo de protección en [`.afterpack/receipts/`](#files). `verify` encuentra el recibo de `[dir]` del mismo modo que la ejecución, así que funciona desde cualquier directorio. Vuelve a calcular el hash de cada archivo que el recibo nombra y falla cuando alguno ya no coincide, cuando el recibo falta o cuando procede de otro build.

```bash
npx afterpack@latest verify .        # a project root: looks in ./ then ./.next/
npx afterpack@latest verify dist     # or the build output directory itself
npx afterpack@latest verify build    # SvelteKit's adapter copy; also .output/public, out/
```

Un directorio que un framework copió de su salida de build, como el `build/` de SvelteKit, el `.output/public/` de Nuxt o el `out/` de Next, se comprueba contra el recibo del directorio que copió. `verify` asocia la copia a ese recibo por sus archivos y comprueba cada hash, así que un archivo modificado hace fallar la comprobación y se nombra. Apúntalo a la raíz del despliegue en sí. La salida de texto añade entonces `· copy of <source dir>/`.

No lee ninguna configuración del motor, solo [`--diagnostics.format`](#machine-readable-output) y `--diagnostics.level`. Con `--diagnostics.format=json`, el campo `receipt` del resumen indica el recibo que comprobó, y `copiedFrom` indica el directorio del que se hizo la copia. Ejecútalo como último paso antes de desplegar; consulta [Builds y CI](https://www.afterpack.dev/es/docs/builds).

También falla cuando una ejecución o un restore detenidos dejaron un archivo temporal `.afterpack-tmp` en el directorio de build. Consulta [Una ejecución que se detuvo a medias](#a-run-that-stopped-partway).

## `afterpack restore [dir]`

El deshacer. Antes de escribir nada, una ejecución copia tus originales en `.afterpack/backups/<build dir>/` y registra cada archivo que va a crear, modificar, renombrar o eliminar. `restore` devuelve cada archivo a su nombre original con sus bytes originales, deshace los renombrados y las referencias reescritas, y borra la copia de seguridad y el recibo que escribió la ejecución.

```bash
npx afterpack@latest restore          # every backup under the project root
npx afterpack@latest restore dist     # only the run over dist/
```

Si lo apuntas a un directorio de build, restaura solo las ejecuciones sobre ese directorio, sobre un directorio dentro de él o sobre el build que lo contiene. Si lo apuntas a la raíz del proyecto, restaura todas las copias de seguridad que hay allí. Cuando ninguna copia de seguridad cubre la ruta, falla y lista los directorios que tienen una. Encuentra `.afterpack/` a partir de `[dir]` del mismo modo que una ejecución, y también lee una carpeta `.afterpack/backup/` que escribió una versión anterior.

Falla de forma segura (fail closed): cada archivo registrado se comprueba *antes* de escribir nada, de modo que un archivo que hayas editado o recompilado desde la ejecución detiene la restauración, no se restaura nada, y el comando nombra el archivo y sale con `1`. Sin copia de seguridad se niega directamente. Un restore que se detuvo a medias lo termina el siguiente `restore`. No lee ninguna configuración del motor más allá de [`--diagnostics.format`](#machine-readable-output).

### Una ejecución que se detuvo a medias

Una ejecución que falla por un error deshace sus propias escrituras antes de salir. Cada archivo se escribe en un temporal `<file>.afterpack-tmp` y después se renombra a su sitio, así que una ejecución interrumpida nunca deja un archivo escrito a medias. La copia de seguridad de una ejecución interrumpida queda marcada como inacabada, y la siguiente ejecución de `afterpack` sobre el mismo directorio comprueba primero la salida:

| La salida del build contiene | La siguiente ejecución |
|---|---|
| Lo que escribió tu bundler y lo que escribió la ejecución detenida, nada más | Falla con salida `1`. Ejecuta `afterpack restore` para dejar la salida como la escribió tu bundler, o recompila desde el código fuente y vuelve a ejecutar. |
| Un build nuevo, o exactamente lo que escribió tu bundler, sin nada de la ejecución detenida | Descarta la copia de seguridad obsoleta con un aviso y se ejecuta. |
| Una mezcla: algunos archivos recompilados y otros que aún contienen la salida de la ejecución detenida | Falla con salida `1` y nombra los archivos recompilados, y `restore` también se niega. Recompila toda la salida desde el código fuente y vuelve a ejecutar, o copia los originales de los demás archivos desde la carpeta de copia de seguridad que nombra el mensaje. |

Con [`--build.backup=false`](https://www.afterpack.dev/es/docs/config#build-backup) no se escribe ninguna copia de seguridad, así que una ejecución interrumpida no se puede deshacer: recompila desde el código fuente. AfterPack no fuerza el volcado de sus escrituras a disco, así que tras un corte de corriente durante una ejecución o un restore, recompila también desde el código fuente.

### Ejecuciones en paralelo y bloqueos

Una ejecución y un restore mantienen cada uno el bloqueo de su directorio de build, `.afterpack/backups/<build dir>/lock`, hasta que terminan. Las ejecuciones sobre directorios de build distintos, como dos apps de un mismo repositorio, van en paralelo. Una segunda ejecución sobre el mismo build, incluido un directorio dentro de él como `.next/static/chunks/` mientras se protege `.next/`, falla con salida `1` y nombra la ejecución que mantiene el bloqueo. Un bloqueo cuyo proceso en esta máquina ya terminó, o que tiene más de dos horas, se toma con un aviso. Si no hay ninguna ejecución en curso y el bloqueo sigue ahí, borra el archivo que nombra el mensaje.

## `afterpack audit <url>`

Escanea un sitio **desplegado** en busca de secretos filtrados, código fuente expuesto y JavaScript sin proteger, y transmite los hallazgos a medida que avanza el escaneo. No lee ninguna configuración y no envía nada más que la URL. Consulta [Auditoría](https://www.afterpack.dev/es/docs/audit) para la referencia completa del comando.

```bash
npx afterpack@latest audit example.com
```

## Salida legible por máquina

`--diagnostics.format=json` escribe exactamente un documento JSON en stdout y nada más; cada línea legible por humanos pasa a stderr. Funciona desde el flag, desde `AFTERPACK_diagnostics_format=json` o desde `diagnostics.format` en `afterpack.json`, y `verify` y `audit` también lo respetan. Combínalo con `diagnostics.level=none` para una ejecución que no imprima nada más que el documento. Esta es la forma que los pasos de CI y los agentes de IA deberían leer en lugar de analizar la salida de texto; el paquete también incluye un `SKILL.md` que documenta la CLI para un agente que la invoque directamente.

```bash
npx afterpack@latest dist/ --diagnostics.format=json --diagnostics.level=none
```

## Códigos de salida

| Código | Significado |
|---|---|
| `0` | Éxito. Cada archivo recopilado fue ofuscado y escrito. También lo devuelven [`--help` y `--version`](#usage). |
| `1` | Fallo. No se produjo nada utilizable: una ruta que no existe, ningún JavaScript encontrado bajo ella, cualquier error del motor, un `verify` fallido, un escaneo `audit` fallido o un build con clave Pro cuya llamada a la nube falló. |
| `2` | Parcial. Reservado para un build con la cuota agotada; hoy ningún build lo devuelve. |
| `3` | Límite de tamaño. [`inflation.max`](https://www.afterpack.dev/es/docs/config#inflation-max) no pudo alcanzar el objetivo de complejidad (`DIAG_SIZE_CAP_REACHED`). |
| `4` | Pro necesario. Una entrada de [`regions`](https://www.afterpack.dev/es/docs/config#regions) eleva la protección por encima de la configuración del programa y necesita una [`key`](https://www.afterpack.dev/es/docs/config#key) (`DIAG_PRO_DIRECTIVE_REQUIRES_KEY`). La CLI no lee directivas del código fuente, así que solo `regions` llega a esta salida. |
| `5` | Reflexión. Se detectó un patrón de reflexión en tiempo de ejecución sin [`reflection.allow`](https://www.afterpack.dev/es/docs/config#reflection-allow) (`DIAG_REFLECTION_NOT_ACKNOWLEDGED`). |
| `6` | Actualización necesaria. La nube de AfterPack, o este `afterpack`, necesita un `@afterpack/core` más reciente. No se escribió nada. |
| `64` | Uso incorrecto. Un flag o un comando desconocidos, un valor mal formado o un argumento de ruta duplicado. |

Usa [`paths.exclude`](https://www.afterpack.dev/es/docs/config#paths-exclude) para excluir un archivo que debe publicarse intacto.

Un build Pro con una [`key`](https://www.afterpack.dev/es/docs/config#key) resuelta falla de forma segura (fail closed). Si la llamada a la nube falla, el build se detiene en lugar de recurrir a la salida del nivel Free. `4` es la salida de un build Free con una entrada de `regions` que necesita una key; `5` es la salida de un patrón de reflexión sin reconocer en cualquier build, Free o Pro; `2` está reservado para un futuro build con la cuota agotada y hoy ningún build lo devuelve. Consulta [Códigos de salida](https://www.afterpack.dev/es/docs/diagnostics#exit-codes) para el contrato completo.

## Siguiente

- [Configuración](https://www.afterpack.dev/es/docs/config): cada opción y las cuatro formas que pueden establecerla.
- [Presets](https://www.afterpack.dev/es/docs/presets): la escalera de cinco peldaños y lo que cuesta cada peldaño.
- [Auditoría](https://www.afterpack.dev/es/docs/audit): la referencia completa de `afterpack audit`.
- [Diagnósticos](https://www.afterpack.dev/es/docs/diagnostics#exit-codes): el contrato de salida, la regla fail closed y cada código `DIAG_*`.
- [Frameworks](https://www.afterpack.dev/es/docs/frameworks): la vía del plugin, mejor cuando existe uno para tu stack.
- [Inicio rápido](https://www.afterpack.dev/es/docs/quickstart): el camino más corto desde la instalación hasta un [Protection Map](https://www.afterpack.dev/es/docs/quickstart#check-the-result).
