La línea de comandos
stxt valida, formatea y describe documentos STXT desde un terminal, un script o
un trabajo de integración continua.
Usa la biblioteca TypeScript @stxt-lang/core y no lleva parser
propio: los errores y sus códigos son los mismos que en la extensión de VS Code, el
playground y las bibliotecas. El uso sobre un proyecto completo, con su directorio
.stxt/, está en El entorno de trabajo.
Instalación
Se publica en npm como
@stxt-lang/cli y necesita
Node 20 o superior:
npm install -g @stxt-lang/cli
stxt --version
stxt 1.0.4 (@stxt-lang/core 1.0.3, spec 2026-09-07)
--version muestra la versión del comando, la de la biblioteca y la fecha de
STXT-SPEC que esta implementa. Sin instalación, con npx:
npx @stxt-lang/cli validate --recursive docs/
Dentro de la línea 1.x del paquete son estables los comandos, sus opciones, los
códigos de salida y --format json. La salida en texto puede cambiar.
Sinopsis
stxt [--version | --help]
stxt validate <file|dir|->... [--recursive] [--format text|json] [--warn-schema | --no-schema]
[--verbose] [--max-nesting N] [--max-line-length N] [--max-input-size N]
stxt format <file|dir|->... [--recursive] [--tabs | --spaces] [--write | --check] [--clean]
[--verbose] [--max-nesting N] [--max-line-length N] [--max-input-size N]
stxt describe <file|-> [--max-nesting N] [--max-line-length N] [--max-input-size N]
stxt schemas [path]
stxt install <file> [--local | --user | --system | --root <dir>] [--force] [--ignore-non-definitions]
| Comando | Qué hace |
|---|---|
stxt validate |
Parsea y valida documentos contra las gramáticas que resuelve; sin salida si todo pasa |
stxt format |
Reescribe documentos en forma canónica, conservando comentarios |
stxt describe |
Emite el árbol lógico de un documento como JSON (STXT-TREE-SPEC) |
stxt schemas |
Muestra la cadena de resolución y qué gramática aplica a cada namespace |
stxt install |
Valida una gramática y la instala en un nivel de la cadena de resolución |
Convenciones comunes a todos los comandos:
- Las opciones son largas, con doble guion. Cuatro tienen alias corto:
-v(--version),-h(--help),-r(--recursive) y-w(--write). --versiony--helpvalen en cualquier posición y tienen precedencia. No hay ayuda por comando:stxt validate --helpimprime la general.- Una opción o un comando desconocidos son errores de uso: código
2, sin realizar ninguna acción. - Los resultados van por la salida estándar, incluido el informe de
validate. Los errores de uso y de lectura, los de sintaxis deformatydescribe, y el progreso de--verbose, van por la salida de error. -designa la entrada estándar envalidate,formatydescribe, una sola vez por llamada, y el documento se reporta como<stdin>. Sin argumentos, ningún comando lee la entrada estándar: es un error de uso.- Ningún comando reescribe ficheros sin una opción explícita:
formatsolo escribe con--write, einstallsolo sobrescribe con--force.
Códigos de salida
| Código | Significado |
|---|---|
0 |
Éxito: los documentos validan, no hay nada que reformatear, la definición se ha instalado |
1 |
Fallo de los documentos: errores de sintaxis o de gramática, ficheros que --check cambiaría, un fichero ilegible, una definición que no se puede instalar, una cadena de resolución con errores en schemas |
2 |
Uso incorrecto: comando u opción desconocidos, falta un argumento, opciones incompatibles, un directorio sin --recursive |
stxt validate
Parsea cada documento, resuelve su cadena de gramáticas (ver Resolución de
gramáticas y STXT_PATH) y lo valida contra la gramática de cada namespace que use.
Si todo pasa, no escribe nada y termina con 0.
| Opción | Efecto |
|---|---|
--recursive, -r |
Desciende en los directorios y valida todos sus *.stxt, ordenados por nombre; los .stxt/ se saltan |
--format text |
Un hallazgo por línea, más un resumen (por defecto) |
--format json |
Los mismos hallazgos como array JSON |
--warn-schema |
Los errores de gramática se reportan como avisos y no hacen fallar; los de sintaxis, sí |
--no-schema |
Solo sintaxis: no resuelve ni aplica ninguna gramática |
--verbose |
Escribe Validating <fichero> por la salida de error antes de cada documento |
--max-nesting N, --max-line-length N, --max-input-size N |
Los límites del parser (STXT-SPEC §11.2): niveles de anidamiento, longitud de línea y tamaño total de la entrada; por defecto 100, 10000 y 10000000; -1 desactiva el límite |
Un directorio exige --recursive; sin él es un error de uso (2). Ficheros,
directorios y - se pueden mezclar en la misma llamada.
Un límite excedido se reporta como un error de parseo más y corta el parseo de ese
documento. validate parsea en streaming: la memoria que usa es del orden del mayor
nodo raíz y no del documento. Un documento mayor que el tamaño por defecto se valida
con --max-input-size -1.
En modo texto, los hallazgos de cada documento se escriben al terminar ese documento,
y el recuento, al final. El array de --format json se escribe entero al final.
--verbose muestra el progreso sin tocar la salida estándar:
stxt validate --recursive --verbose docs/
Validating /home/ana/libros/docs/book.stxt
Con -, la cadena de gramáticas es la del directorio actual, la que muestra
stxt schemas sin argumento:
git show HEAD:docs/book.stxt | stxt validate -
Los hallazgos
Con el proyecto de El entorno de trabajo (la plantilla
com.acme.book en .stxt/), un docs/book.stxt con una fecha no válida y sin el
ISBN obligatorio:
stxt validate docs/book.stxt
/home/ana/libros/docs/book.stxt:6: [INVALID_VALUE] Published: Invalid date (1 de octubre de 2025) (error)
/home/ana/libros/docs/book.stxt:1: [TOO_FEW_CHILDREN] 0 nodes of 'com.acme.book:isbn' and min is 1 (error)
2 error(s), 0 warning(s)
Cada línea es fichero:línea: [CÓDIGO] mensaje (severidad), con la ruta absoluta, y
al final va el recuento. Los códigos son estables y los mismos en todas las
herramientas. Los más habituales:
| Código | Ámbito |
|---|---|
INDENTATION_MIXED, INDENTATION_LEVEL_NOT_VALID, INVALID_LINE |
Sintaxis (STXT-SPEC) |
INVALID_VALUE, TOO_FEW_CHILDREN, CHILD_NOT_DECLARED, NODE_NOT_DEFINED_IN_SCHEMA |
Gramática (STXT-SCHEMA-SPEC) |
SCHEMA_NOT_FOUND |
El documento usa un namespace que la cadena no define |
DISCOVERY_DUPLICATE_NAMESPACE, DISCOVERY_NOT_A_DEFINITION |
La propia cadena de resolución (STXT-DISCOVERY-SPEC) |
FILE_NOT_READABLE |
El fichero no existe o no se puede leer |
Un error de cardinalidad se señala en la línea del padre (Book, línea 1). Los
errores de la cadena de resolución (una gramática no válida en .stxt/, dos
definiciones del mismo namespace en el mismo nivel) se reportan en la línea 0 del
fichero causante y hacen fallar la validación:
stxt validate docs/book.stxt
/home/ana/libros/.stxt/otro/copia.stxt:0: [DISCOVERY_DUPLICATE_NAMESPACE] Duplicate definition for namespace 'com.acme.book' at level /home/ana/libros/.stxt: already defined in /home/ana/libros/.stxt/@stxt.template/com.acme.book.stxt (error)
1 error(s), 0 warning(s)
Sin gramática, o con la gramática en aviso
- Un documento sin namespace no se valida y pasa (STXT-SCHEMA-SPEC §5).
- Uno con namespace que la cadena no define produce
SCHEMA_NOT_FOUND, también con la cadena vacía. - Una definición (
@stxt.schemao@stxt.template) se comprueba siempre contra su meta-esquema.
--warn-schema rebaja los errores de gramática a avisos, para introducir una
gramática en un proyecto con documentos anteriores a ella:
stxt validate --warn-schema docs/book.stxt
/home/ana/libros/docs/book.stxt:6: [INVALID_VALUE] Published: Invalid date (1 de octubre de 2025) (warning)
/home/ana/libros/docs/book.stxt:1: [TOO_FEW_CHILDREN] 0 nodes of 'com.acme.book:isbn' and min is 1 (warning)
0 error(s), 2 warning(s)
Termina con 0. Con --no-schema solo se comprueba la sintaxis: el mismo documento
pasa sin salida.
Salida JSON
Con --format json la salida es un array con un objeto por hallazgo (file,
line, code, message, severity), o [] si todo pasa, sin resumen. El código
de salida es el mismo que en modo texto.
stxt validate --format json docs/book.stxt
[{"file":"/home/ana/libros/docs/book.stxt","line":6,"code":"INVALID_VALUE","message":"Published: Invalid date (1 de octubre de 2025)","severity":"error"},{"file":"/home/ana/libros/docs/book.stxt","line":1,"code":"TOO_FEW_CHILDREN","message":"0 nodes of 'com.acme.book:isbn' and min is 1","severity":"error"}]
# Cuántos hallazgos de cada código hay en todo el proyecto
stxt validate --format json --recursive docs/ | jq -r '.[].code' | sort | uniq -c
stxt format
Reescribe documentos línea a línea, según el reformateado de STXT-TREE-SPEC §12:
- Normaliza la indentación a tabuladores (o a cuatro espacios con
--spaces), deja un solo espacio tras los dos puntos y quita los espacios de final de línea. - Conserva los comentarios, las líneas en blanco, el final de línea original (CRLF incluido) y la ausencia de salto final.
- El contenido de los bloques
>>solo se reindenta. Las líneas en blanco finales de un bloque no son contenido y quedan sin indentar. - De la indentación de un comentario convierte solo las unidades enteras (tabuladores o grupos de cuatro espacios).
- Escribe el namespace únicamente donde el fuente lo escribió.
Tres modos, mutuamente excluyentes:
| Modo | Qué hace | Sale con 1 si... |
|---|---|---|
| (por defecto) | Imprime el resultado por la salida estándar; no escribe en disco | Algún documento no parsea |
--check |
Lista los ficheros que cambiarían (<fichero>: would be reformatted); no escribe nada |
Alguno cambiaría, o no parsea |
--write, -w |
Reescribe cada fichero in situ, solo si cambia, y lo indica (Formatted <fichero>) |
Algún documento no parsea |
Otras opciones:
| Opción | Efecto |
|---|---|
--tabs / --spaces |
Indentar con tabuladores (por defecto) o con cuatro espacios |
--recursive, -r |
Igual que en validate: desciende, ordena por nombre, salta los .stxt/ |
--clean |
Reserializa el árbol lógico (STXT-TREE-SPEC §11): se pierden comentarios y líneas en blanco |
--verbose |
Escribe Formatting <fichero> (Checking <fichero> con --check) por la salida de error antes de cada documento |
--max-nesting N, --max-line-length N, --max-input-size N |
Los límites del parser, como en validate |
--check equivale a gofmt -l o prettier --check. Un documento con errores de
sintaxis se reporta y no se reformatea. format no aplica gramáticas. Combinar
--write con --check, o --tabs con --spaces, es un error de uso (2).
Un documento escrito con espacios, con un comentario, una línea en blanco y espacios de más:
# Ficha del libro
Book (com.acme.book):
Title: Arquitectura de software moderna
Authors:
Author: María Pérez
ISBN: 978-84-123456-7-8
stxt format docs/book.stxt
# Ficha del libro
Book (com.acme.book):
Title: Arquitectura de software moderna
Authors:
Author: María Pérez
ISBN: 978-84-123456-7-8
Los otros dos modos sobre el mismo fichero:
stxt format --check docs/book.stxt
/home/ana/libros/docs/book.stxt: would be reformatted
# código de salida 1
stxt format --write docs/book.stxt
Formatted /home/ana/libros/docs/book.stxt
stxt format --check docs/book.stxt
# ya no escribe nada: código de salida 0
Con -, format es un filtro: lee de la entrada estándar y escribe en la salida
estándar. --check - responde <stdin>: would be reformatted y 1 si cambiaría.
--write - es un error de uso:
stxt format --spaces - < docs/book.stxt
stxt format --write -
stxt format: --write cannot be used with - (the standard input); the result is printed to stdout
stxt describe
Escribe por la salida estándar el árbol lógico de un documento en el JSON canónico
de STXT-TREE-SPEC: un array de nodos raíz, cada uno con name,
canonicalName, el namespace efectivo y la forma ("inline" con value y
children, o "block" con lines). No incluye posiciones ni comentarios.
No resuelve gramáticas ni valida. Si el documento tiene errores de sintaxis no emite
un árbol parcial: los informa por la salida de error y termina con 1. Acepta - y
los mismos límites del parser que validate.
Book (com.acme.book):
Title: Arquitectura de software moderna
Chapter: Introducción
Content >>
Conceptos básicos y objetivos del libro.stxt describe docs/book.stxt
[
{
"name": "Book",
"canonicalName": "book",
"namespace": "com.acme.book",
"form": "inline",
"value": "",
"children": [
{
"name": "Title",
"canonicalName": "title",
"namespace": "com.acme.book",
"form": "inline",
"value": "Arquitectura de software moderna",
"children": []
},
{
"name": "Chapter",
"canonicalName": "chapter",
"namespace": "com.acme.book",
"form": "inline",
"value": "Introducción",
"children": [
{
"name": "Content",
"canonicalName": "content",
"namespace": "com.acme.book",
"form": "block",
"lines": [
"Conceptos básicos y objetivos del libro."
]
}
]
}
]
}
]
# El título del libro, con jq
stxt describe docs/book.stxt | jq -r '.[0].children[] | select(.canonicalName == "title") | .value'
stxt schemas
Muestra la cadena de resolución de un documento o de un directorio (por defecto, el
actual) y, para cada namespace, la definición activa y su fichero. Es el primer
diagnóstico ante un SCHEMA_NOT_FOUND.
stxt schemas docs
Resolution chain for /home/ana/libros/docs:
/home/ana/libros/.stxt
Namespaces:
com.acme.book <- /home/ana/libros/.stxt/@stxt.template/com.acme.book.stxt
La cadena lista los niveles en orden de precedencia. Si el proyecto está dentro de
otro con su propio .stxt/, aparecen los dos, y para cada namespace gana el más
cercano. Sin ningún nivel:
stxt schemas
Resolution chain for /home/ana/notas:
(empty: no .stxt directory found)
No namespaces resolved.
Los errores de la cadena van por la salida de error, en un bloque Errors: al final.
Con dos definiciones del mismo namespace en el mismo nivel, el namespace se queda
sin definición activa, y validate falla con el mismo error:
stxt schemas docs
Resolution chain for /home/ana/libros/docs:
/home/ana/libros/.stxt
No namespaces resolved.
Errors:
DISCOVERY_DUPLICATE_NAMESPACE /home/ana/libros/.stxt/otro/copia.stxt: Duplicate definition for namespace 'com.acme.book' at level /home/ana/libros/.stxt: already defined in /home/ana/libros/.stxt/@stxt.template/com.acme.book.stxt
Termina con 1 si la cadena tiene errores o la ruta no existe, y con 0 en
cualquier otro caso, también con la cadena vacía.
stxt install
Instala las definiciones de un fichero en un nivel de la cadena de resolución. Antes
de escribir comprueba que el fichero tenga extensión .stxt, que parsee y que cada
nodo raíz sea una definición que valide contra su meta-esquema; si algo falla, no
escribe nada. Cada definición se escribe por separado, en forma canónica, como
<nivel>/@stxt.schema/<namespace>.stxt o <nivel>/@stxt.template/<namespace>.stxt.
Esa disposición es una convención de la CLI: STXT-DISCOVERY-SPEC §3 no da significado a los nombres de fichero ni a los subdirectorios de un nivel, y una gramática colocada a mano puede estar en cualquier ruta.
| Nivel | Opción | Dónde escribe |
|---|---|---|
| Proyecto | --local |
./.stxt (el directorio actual; por defecto) |
| Usuario | --user |
~/.stxt (%USERPROFILE%\.stxt en Windows) |
| Sistema | --system |
/etc/stxt (%ProgramData%\stxt en Windows) |
| Cualquiera | --root <dir> |
El directorio que se indique, exista o no |
| Opción | Efecto |
|---|---|
--force |
Sobrescribe una definición ya instalada para ese namespace (coincidencia de ruta o de namespace) |
--ignore-non-definitions |
Instala las definiciones del fichero y salta los demás nodos raíz, en vez de fallar |
stxt install book-template.stxt
Installed com.acme.book (@stxt.template) to /home/ana/libros/.stxt/@stxt.template/com.acme.book.stxt
Los casos que hacen fallar la instalación (código 1):
stxt install book-template.stxt
stxt install: /home/ana/libros/.stxt/@stxt.template/com.acme.book.stxt already exists (use --force to overwrite)
stxt install docs/book.stxt
stxt install: docs/book.stxt:1: root node 'Book' belongs to 'com.acme.book', not to @stxt.schema or @stxt.template (use --ignore-non-definitions to install only the definitions)
stxt install broken.stxt
stxt install: broken.stxt: invalid @stxt.template definition: Type not valid: NOTATYPE
stxt install notes.txt
stxt install: not an STXT document (.stxt expected): notes.txt
Resolución de gramáticas y STXT_PATH
validate, schemas e install usan la cadena de
STXT-DISCOVERY-SPEC §4, la misma que la extensión de
VS Code y las bibliotecas:
- Los niveles son todos los directorios
.stxt/desde la carpeta del documento hacia arriba, después~/.stxty por último/etc/stxt. - Dentro de un nivel se cargan todos los ficheros
.stxt, recursivamente, y cada uno debe ser una definición. - La precedencia es por namespace: prevalece el nivel más cercano que lo defina, y los demás niveles aportan los namespaces que aquel no define.
- Dos definiciones del mismo namespace en el mismo nivel son un error, y ese namespace se queda sin definición.
La variable de entorno STXT_PATH sustituye la cadena entera por una lista de
directorios separados por : (; en Windows), en orden de precedencia. Las entradas
no tienen por qué llamarse .stxt, y una que no exista no aporta nada. En CI evita
depender del ~/.stxt o del /etc/stxt de la máquina:
STXT_PATH=./.stxt stxt validate --recursive docs/
Una STXT_PATH definida pero vacía deja la cadena vacía: validate falla con
SCHEMA_NOT_FOUND en todo documento con namespace, salvo con --no-schema o
--warn-schema, y schemas muestra (empty: STXT_PATH provides no directories).
Tareas frecuentes
Integración continua: los documentos validan y están formateados.
npx @stxt-lang/cli validate --recursive docs/
npx @stxt-lang/cli format --check --recursive docs/
Formatear un proyecto entero por primera vez, pasándolo a espacios. Los .stxt/
se saltan; las gramáticas se formatean en una llamada aparte.
stxt format --write --spaces --recursive .
Un documento que no está en disco, con -:
curl -s https://example.com/api/book.stxt | stxt validate -
curl -s https://example.com/api/book.stxt | stxt describe - | jq '.[0].name'