Referencia de la CLI fp
El binario fp ejecuta workspaces de Fetchpier sin Electron. Ofrece salida interactiva en la terminal,
reportes legibles por máquinas, códigos de salida estables y una API programática de Node.js.
Un workspace es una carpeta que contiene .fetchpier/settings.json. Las solicitudes son los archivos
.http bajo su carpeta requests/; los entornos son las carpetas bajo environments/.
Comandos
Section titled “Comandos”| Comando | Descripción | Necesita un workspace |
|---|---|---|
fp run [paths...] | Alias de fp request run. | Sí |
fp request run [paths...] | Ejecuta archivos .http y/o carpetas. Sin path, ejecuta el requests/ del workspace. | Sí |
fp env list | Imprime el nombre de carpeta de cada entorno, uno por línea — los nombres que acepta --env. | Sí |
fp env current | Imprime el entorno que elegiría una ejecución (--env > FETCHPIER_ENV > default). | Sí |
fp init [name] [--template rest|graphql] | Crea un workspace en ./<name>, o en la carpeta actual si se omite name, con una solicitud inicial (rest por defecto). | No |
fp --help, fp <command> --help | Ayuda del programa o de un comando. | No |
fp -V, fp --version | Imprime la identidad de la CLI, su versión y el aviso de copyright. | No |
Cuando un comando necesita un workspace y no se encuentra ninguno, sale con el código 4.
fp --version imprime en stdout el nombre del producto, la versión de la CLI y la línea de copyright
del proyecto. Invocar fp sin argumentos imprime el mismo banner arriba del texto de uso en stderr y
conserva el código de salida de uso. Ninguna otra invocación imprime un banner, así que un reporte JSON
enviado por stdout nunca viene precedido por uno. El número de versión de la CLI es independiente del
de la aplicación de escritorio.
Qué archivos se ejecutan
Section titled “Qué archivos se ejecutan”-
Sin path: todos los archivos
.httpbajo la carpetarequests/del workspace, de forma recursiva — el mismo conjunto desde cualquier directorio, dentro o fuera del workspace. -
Los paths explícitos (archivos o carpetas, tantos como quieras) son relativos al directorio actual, como en cualquier otra herramienta de línea de comandos, así que el autocompletado de la shell siempre produce un argumento válido. Si un path no existe en el directorio actual pero sí dentro del workspace, el error sugiere el path que debes escribir:
$ fp run requests/auth/login.http --workspace my-apiError: Path not found: requests/auth/login.httpDid you mean my-api/requests/auth/login.http? Paths are relative to the current directory. -
Las carpetas se recorren en orden de nombre;
.runs/,.fetchpier/y.git/se omiten. -
Un archivo
.httppuede contener varias solicitudes (separadores###); solo se ejecuta la primera, con un aviso que nombra el archivo. -
Una carpeta de destino (o el
requests/del workspace) sin ningún archivo.httpdetiene la ejecución con el código de salida19: una ejecución que no envía nada no es un éxito.
fp init
Section titled “fp init”fp init crea .fetchpier/, un entorno default con una variable baseUrl,
requests/example.http y un .gitignore (solo si no existe ninguno). Nunca sobrescribe archivos
existentes, y falla con el código de salida 4 si el destino ya es un workspace. Al final imprime el
comando a ejecutar a continuación (fp run --workspace my-api, o fp run cuando inicializas la carpeta
actual), que funciona tal como se imprime desde el mismo directorio.
Opciones de ejecución
Section titled “Opciones de ejecución”| Opción | Efecto |
|---|---|
-w, --workspace <path> | Elige el workspace explícitamente. |
-e, --env <name> | Elige un entorno por nombre de carpeta (sin distinguir mayúsculas). |
--env-var KEY=VALUE | Sobrescribe una variable para esta ejecución; repetible. Un script que más adelante define la misma variable prevalece a partir de ese momento. |
--persist-env | Guarda los cambios de variables hechos por scripts (fp.environment.set / remove) en los valores locales, exactamente como lo hace el escritorio. Sin esta opción, solo se aplican al resto de la ejecución. |
--bail | Se detiene después de la primera solicitud fallida — un test fallido, un error de script, un archivo sin solicitud o una solicitud que no obtuvo respuesta. |
--delay <ms> | Espera entre solicitudes (número entero, 0 o mayor). |
--timeout <ms> | Timeout por solicitud. Por defecto 30000 (30 s, como el escritorio); 0 lo desactiva — y es la única forma de hacerlo. |
--proxy <url> | Envía todas las solicitudes a través de este proxy (http://user:pass@host:port). Prevalece sobre HTTPS_PROXY / HTTP_PROXY. |
--no-proxy | Ignora HTTPS_PROXY / HTTP_PROXY / NO_PROXY en esta ejecución. No se puede combinar con --proxy. |
--insecure | Desactiva la verificación de certificados TLS en esta ejecución. |
--reporter-json <file> | Escribe JSON; usa - para stdout, lo que silencia el reporter para humanos. |
--reporter-json-no-body | Omite los bodies de las respuestas en el JSON. |
--reporter-junit <file> | Escribe JUnit XML. |
--reporter-html <file> | Escribe un reporte HTML autocontenido. |
--reporter-html-only-failures | Abre el reporte HTML con el filtro de fallos ya aplicado. |
--save-history | Registra cada solicitud que obtuvo respuesta en el historial del workspace (requests/.runs/), como el registro de actividad del escritorio. |
--suppress-exit-code | Devuelve 0 para los resultados de la ejecución; los errores fatales de preparación siguen siendo distintos de cero. |
--show-secrets | No redacta credenciales ni cookies en la salida. Úsalo con cuidado. |
--ascii | Usa glifos ASCII en lugar de Unicode. |
--no-color | Desactiva los colores ANSI; también se respetan NO_COLOR y FORCE_COLOR. |
--silent | Suprime stdout y conserva stderr. |
-v, -vv, -vvv | Aumenta la verbosidad (ver abajo). |
--timeout y --delay aceptan números enteros de 0 a 2147483647 (el límite de timers del runtime,
unos 24,8 días); cualquier otro valor es un error de uso (salida 3). Una opción de valor único dada
dos veces conserva su último valor, la convención habitual de la línea de comandos — dos
--reporter-json escriben solo el último.
Verbosidad
Section titled “Verbosidad”Los niveles son acumulativos y son los mismos para una o varias solicitudes:
| Nivel | Agrega |
|---|---|
| por defecto | Las líneas de solicitud y respuesta, y toda la salida fp.log / warn / error de cada script. |
-v | La lista de tests de cada solicitud, la URL completa en lugar de su path, y si salió via proxy o direct. |
-vv | Las cabeceras de la solicitud y de la respuesta. |
-vvv | Los bodies de la solicitud y de la respuesta, cada uno cortado a 64 KB (el reporte JSON tiene el body completo). |
La redacción y el enmascarado de secretos se aplican en todos los niveles. Un body binario nunca se
vuelca en la terminal: -vvv imprime en su lugar una línea con su tamaño y su tipo (una respuesta
comprimida que se decodificó se evalúa por su contenido decodificado). El resto del texto se imprime tal
como se recibió.
Resolución de contexto
Section titled “Resolución de contexto”- Workspace:
--workspace>FETCHPIER_WORKSPACE> búsqueda ascendente de una carpeta que contenga.fetchpier/settings.json, empezando en el directorio actual y deteniéndose por encima de tu directorio home. - Entorno:
--env>FETCHPIER_ENV>default, comparado sin distinguir mayúsculas con el nombre de la carpeta del entorno. La CLI nunca lee la preferencia de entorno activo del escritorio, lo que mantiene predecible el comportamiento en CI. - Variables: los valores del entorno, luego los valores locales de la máquina, luego los overrides
de
--env-var, y luego lo que hayan definido los scripts anteriores de la ejecución. Las referencias{{$env.NAME}}se resuelven desde un archivo.enven la raíz del workspace y, después, desde el entorno del proceso.
fp env list imprime un warning por cada carpeta de entorno cuyo config.json no se puede leer.
fp env current imprime el nombre que elegiría una ejecución sin verificar que exista; una ejecución
con un entorno desconocido sale con el código 6 y lista los disponibles, y una cuyo config.json no
se puede leer sale con el código 4 nombrando el archivo. Igual que el escritorio, fp run y
fp env list mantienen el nombre visible de un entorno sincronizado con su carpeta: si el name de
config.json no coincide con la carpeta (por ejemplo, después de renombrar la carpeta a mano),
reescriben ese único campo.
Variables de entorno
Section titled “Variables de entorno”| Variable | Propósito |
|---|---|
FETCHPIER_WORKSPACE | Carpeta del workspace, cuando no se indica --workspace. |
FETCHPIER_ENV | Nombre de la carpeta del entorno, cuando no se indica --env. |
FETCHPIER_WORKSPACE_KEY | Clave del workspace (FPK1-…) usada para descifrar las variables secretas. |
HTTPS_PROXY / HTTP_PROXY | Proxy para destinos https / http. |
NO_PROXY | Destinos que se conectan directamente. |
NO_COLOR | Desactiva los colores (igual que --no-color). |
FORCE_COLOR | Fuerza los colores cuando stdout no es una terminal (0 no los fuerza). |
Variables y secretos durante una ejecución
Section titled “Variables y secretos durante una ejecución”Variables entre solicitudes. Un valor que un script define con fp.environment.set (o elimina con
fp.environment.remove) se aplica a todas las solicitudes posteriores de la misma ejecución — el token
de un login llega a la llamada siguiente. Un valor definido con el nombre de una variable secreta queda
enmascarado como {secret:<name>} en todas partes. Sin --persist-env no se escribe nada en el
workspace.
Variables faltantes. Un {{var}} sin valor en el entorno elegido se envía literalmente, y un
{{$env.NAME}} que no definen ni .env ni el entorno del proceso se envía vacío; cada caso imprime un
warning (también en el reporte JSON, con un code estable) para la solicitud que lo usa. Ninguno de
los dos falla la ejecución — revisa los warnings, o agrega aserciones sobre la respuesta, para que una
credencial faltante haga fallar un pipeline. Un nombre definido con un valor vacío es intencional y no
produce warning. Un percent-encoding malformado también produce un warning y se envía literalmente.
Secretos en scripts. Solo se descifran los secretos que una solicitud referencia (en su URL,
cabeceras, body o auth), así que un script que lee un secreto que su propia solicitud no usa obtiene
undefined. Referéncialo en la solicitud, o pásalo a través de una variable común.
Secretos en CI. Entrega la clave del workspace mediante FETCHPIER_WORKSPACE_KEY, normalmente
inyectada desde el secret store de tu proveedor de CI. La resolución es perezosa: una ejecución que no
toca ningún secreto no necesita clave. Una ejecución que necesita un secreto que no puede resolver se
detiene antes de enviar, con un código de salida dedicado (14–17).
--persist-env después de una rotación de clave. Si un compañero de equipo rotó la clave del
workspace y tú la descargaste, tus valores locales siguen cifrados con la clave anterior hasta que abras
el workspace en la app de escritorio con la clave nueva (que los vuelve a cifrar). Hasta entonces,
fp run --persist-env no guarda las escrituras de scripts en variables secretas, imprime un
warning que nombra la causa y la solución, sigue usando el valor en memoria durante el resto de la
ejecución, y guarda normalmente las escrituras en variables comunes. Un checkout de CI no tiene valores
locales, así que esto solo ocurre en la máquina de un desarrollador.
Comportamiento de red
Section titled “Comportamiento de red”Proxy. HTTPS_PROXY se aplica a destinos https y HTTP_PROXY a destinos http (también en
minúsculas); NO_PROXY excluye hosts, sufijos de dominio, entradas host:port, o todo (*). --proxy
sobrescribe ambas variables; --no-proxy ignora las tres. El proxy activo se muestra en el encabezado
sin credenciales, seguido de la lista NO_PROXY cuando la hay. Una URL de proxy inutilizable detiene la
ejecución antes de enviar nada (código de salida 3); un proxy que no responde hace fallar la solicitud
en el reporte.
Cabeceras por defecto y compresión. Cuando una solicitud no las define, la CLI envía
User-Agent: Fetchpier-CLI/<version> y Accept-Encoding: gzip, deflate, br. Las respuestas comprimidas
(gzip, deflate, br) se decodifican; el reporte JSON incluye compressedBytes, decompressedBytes
y decodingStatus. Un body que no se puede decodificar se conserva tal como se recibió, con un warning,
y fp.response.json() falla con la causa real.
Bodies binarios. Una solicitud cuyo body es un archivo adjuntado en el escritorio (preparado bajo
requests/.files/) se envía exactamente con los bytes de ese archivo, y con el Content-Type de su
tipo de archivo salvo que la solicitud defina uno. Un archivo faltante, o una referencia inválida, hace
fallar esa solicitud como “not run” en lugar de enviarla vacía.
Resultados de las solicitudes
Section titled “Resultados de las solicitudes”El runner ejecuta los pre-request scripts, aplica la auth y las variables, envía la solicitud, captura
las cookies, ejecuta los post-response scripts y evalúa los tests. Continúa después de una solicitud
fallida salvo que se use --bail. Una solicitud que recibió cualquier respuesta — incluida una 4xx o
5xx — pasa salvo que falle alguno de sus tests.
Los fallos de red, los fallos de TLS, los timeouts, una interrupción con una solicitud en vuelo, los
errores de scripts y las aserciones fallidas son resultados de solicitud, no crashes internos. La
ejecución sigue con la próxima solicitud (o se detiene, con --bail), se genera el resumen y se
escriben igual todos los reportes configurados — la ejecución que más necesita inspección es justamente
aquella cuyo servicio estaba caído. Las condiciones que impiden que una ejecución siquiera arranque — un
workspace, entorno o path ausente, una configuración ilegible, un proxy inutilizable, una clave de
workspace faltante — siguen siendo fatales y conservan sus propios códigos de salida.
Una solicitud que no obtuvo respuesta se muestra como no response: <reason> (host inalcanzable, TLS,
timeout, proxy); una que nunca se intentó, como not run: <reason> (un archivo sin solicitud, un
pre-request script que falló, un archivo binario faltante o cuya referencia es inválida). Un timeout
vencido se reporta como timed out after <limit>.
Reportes
Section titled “Reportes”Una sola ejecución puede escribir JSON, JUnit XML y HTML autocontenido a la vez. El JSON está versionado para sus consumidores; JUnit funciona con los dashboards de tests habituales de CI; el HTML funciona sin conexión e incluye filtros de tema y de fallos. Los destinos de los reportes deben apuntar a un directorio padre existente.
- Solo JSON admite stdout.
--reporter-json -escribe en stdout; pasar-a cualquier otro reporter se rechaza con un mensaje claro (código de salida2) en lugar de crear en silencio un archivo llamado literalmente-. - La versión del schema JSON cambia solo ante cambios incompatibles. Cambia únicamente cuando un consumidor tendría que modificar su código para seguir parseando el reporte; los campos opcionales nuevos no la mueven.
- Una solicitud que nunca obtuvo respuesta es siempre un fallo visible. Todos los formatos la muestran como un fallo con su motivo — nunca como una entrada que simplemente falta, ni como un grupo vacío que un dashboard leería como exitoso.
Redacción. Los reportes y la salida de la terminal redactan Authorization /
Proxy-Authorization, la credencial de la auth por API key (en query o cabecera) y los valores de
Cookie / Set-Cookie. --show-secrets los revela, pero las variables secretas se siguen imprimiendo
como {secret:<name>} — incluso en lo que un script registra en el log, en el nombre de un test o en el
mensaje de una aserción fallida. Evita publicar reportes que contengan datos de solicitudes o respuestas
de producción.
Límites del enmascarado. Los secretos se enmascaran por coincidencia exacta, como el enmascarado de logs en CI: un servidor que devuelve un secreto escapado (dentro de JSON, codificado en URL) o un script que lo transforma (lo hashea, lo codifica, lo recorta) no se reconoce, y un secreto muy corto puede enmascarar texto no relacionado que lo contenga. Prefiere secretos de una longitud realista.
TLS e historial
Section titled “TLS e historial”El runner aplica la configuración TLS del workspace exactamente como el escritorio: los certificados de
CA y los certificados de cliente listados en el bloque tls de .fetchpier/settings.json, cuyos
archivos viven bajo .fetchpier/certs/ (ambos se gestionan normalmente desde la configuración del
workspace en el escritorio y se versionan junto con el workspace). Un certificado de cliente se presenta
a los hosts para los que está configurado; una passphrase que referencia una variable secreta se
descifra con FETCHPIER_WORKSPACE_KEY. Los certificados configurados solo en la configuración propia de
la app de escritorio no son visibles para el runner. --insecure desactiva la verificación de
certificados en una ejecución.
El historial está apagado por defecto en la automatización. --save-history registra cada solicitud
que obtuvo respuesta en requests/.runs/ — un registro local para depuración, ignorado por git por
defecto. Igual que el registro de actividad del escritorio, oculta Authorization pero conserva las API
keys y los valores de las cookies tal como se enviaron: no lo subas como artefacto de CI. Los reportes
son el artefacto de CI, y redactan esos valores.
Códigos de salida
Section titled “Códigos de salida”| Código | Significado |
|---|---|
0 | Éxito. |
1 | Falló una solicitud (test fallido, error de script, sin respuesta, o un archivo sin solicitud), o un error de uso (comando u opción desconocidos, fp sin argumentos). Una ejecución con solicitudes fallidas nunca reporta éxito, aunque no declare aserciones. |
2 | Un destino de salida de un reporter es inválido (directorio ausente, o - para un reporter que no es JSON). |
3 | Valor de flag inválido (--timeout, --delay), una URL de proxy inutilizable (flag o variable), o --proxy junto con --no-proxy. |
4 | Workspace no encontrado o inválido — incluido un .fetchpier/settings.json o el config.json de un entorno seleccionado que no se pueden parsear; o fp init sobre una carpeta que ya es un workspace. |
5 | Un path de entrada no existe o no es un archivo/carpeta .http; o el workspace no tiene carpeta requests/. |
6 | Entorno no encontrado. |
7 | --env-var mal formado; se espera KEY=VALUE. |
8 | Reservado para errores fatales de parseo. Un archivo que no se puede parsear como solicitud se reporta como una solicitud fallida (salida 1). |
9 | Reporter desconocido (solo alcanzable a través de la API programática). |
10–13 | Reservados para errores de multipart. Hoy un problema de multipart se reporta como una solicitud fallida con su motivo (salida 1). |
14 | Un secreto referenciado necesita descifrarse pero FETCHPIER_WORKSPACE_KEY no está definida. |
15 | La clave del workspace está mal formada o no corresponde a este workspace. |
16 | No se puede descifrar un valor secreto. |
17 | Un secreto referenciado no tiene valor definido (“needs value”). |
18 | El runtime de Node.js es anterior al mínimo de la CLI (22.19.0). |
19 | Nada que ejecutar: una carpeta de destino (o el requests/ del workspace) no contiene ningún archivo .http. --suppress-exit-code no lo enmascara. |
130 | Interrumpido con Ctrl-C o SIGTERM, después de volcar los reportes parciales. |
255 | Error interno; repórtalo como bug. |
Interrumpir una ejecución cancela la solicitud en vuelo y vuelca los reportes parciales antes de salir
con 130 — sin stack trace, porque una interrupción es un resultado intencional. Las solicitudes ya
completadas se reportan normalmente.
API programática
Section titled “API programática”El paquete admite consumidores ESM y CommonJS:
import { run, init, listEnvironments, currentEnvironment } from '@fetchpier/cli'
// No paths: the workspace's requests/ tree, from any working directory.const summary = await run({ paths: [], workspace: '/path/to/ws', silent: true })console.log(summary.summary.requests) // { total, passed, failed }console.log(summary.summary.tests) // { total, passed, failed }run devuelve el RunSummary estructurado (el schema del reporter JSON) y nunca llama a
process.exit — tu código decide qué hacer con el resultado. Los paths explícitos son relativos al
directorio actual del proceso. Por defecto, run también imprime el reporte de terminal en stdout;
pasa silent: true o tus propios reporters para evitarlo. Las condiciones fatales (workspace, path,
entorno, secretos) rechazan la promesa en lugar de devolver un resumen; un CliError lleva su código de
salida en exitCode.
Ejemplos de CI
Section titled “Ejemplos de CI”GitHub Actions — workspace en la carpeta api/ del repositorio:
- uses: actions/checkout@v4- uses: actions/setup-node@v4 with: node-version: 22- run: npm install -g @fetchpier/cli- run: mkdir -p reports && fp run --env ci --reporter-junit reports/fp.xml env: FETCHPIER_WORKSPACE: ${{ github.workspace }}/api FETCHPIER_WORKSPACE_KEY: ${{ secrets.FETCHPIER_WORKSPACE_KEY }}- if: always() uses: actions/upload-artifact@v4 with: { name: fetchpier-report, path: reports/fp.xml }GitLab CI — workspace en la raíz del repositorio:
api-tests: image: node:22 script: - npm install -g @fetchpier/cli - fp run --reporter-junit report.xml artifacts: when: always reports: junit: report.xmlPara ejecutar un subconjunto, pasa un path relativo al directorio de trabajo del job, por ejemplo
fp run api/requests/smoke.
Modelo de amenazas del sandbox
Section titled “Modelo de amenazas del sandbox”Los scripts pre-request y post-response corren en el mismo sandbox, con la misma API fp.*, que en el
escritorio. El sandbox previene errores accidentales en los scripts; no es una defensa contra un
adversario que haya colocado código malicioso en tu workspace. Si ejecutas colecciones no confiables en
CI, ejecuta fp dentro de un contenedor u otra frontera de aislamiento.
Operaciones no soportadas
Section titled “Operaciones no soportadas”La CLI actual no cambia ni modifica la selección de entorno del escritorio (fp env switch no forma
parte de esta release: el escritorio guarda su entorno activo en su propio almacén de datos de usuario,
fuera del workspace), no renombra ni duplica entornos, no importa schemas, no envía URLs ad-hoc, no
instala completions de shell, no ejecuta solicitudes en paralelo ni acepta un archivo de CA por
ejecución. Configura el material TLS compartido en el workspace y usa el escritorio para importar
schemas y mantener los entornos.