El entorno de trabajo

Cómo organizar un proyecto STXT, dónde colocar su gramática y cómo validar desde el editor, desde la línea de comandos y en integración continua.

Sigue el ejemplo del tutorial, la ficha de un libro. Se usan la línea de comandos stxt (npm install -g @stxt-lang/cli, o npx @stxt-lang/cli sin instalar), Visual Studio Code con la extensión stxt-lang.stxt y el playground; las tres están descritas en Herramientas.

El proyecto y el directorio .stxt/

Un proyecto STXT es un directorio con documentos .stxt y un directorio llamado .stxt/ con sus gramáticas (esquemas y plantillas). Para validar un documento, una herramienta busca .stxt/ en el directorio del documento y en todos sus ascendentes, y después en ~/.stxt y en /etc/stxt. Esa lista es la cadena de resolución del documento, y es la misma en el editor, en la línea de comandos y en las bibliotecas.

Para el ejemplo, un proyecto libros:

libros/
├── .stxt/            las gramáticas del proyecto
└── docs/
    └── book.stxt     los documentos

Dentro de .stxt/ se cargan todos los ficheros .stxt, recursivamente. Ni los nombres de fichero ni los subdirectorios tienen significado. Cada fichero debe ser una definición (@stxt.schema o @stxt.template); cualquier otro contenido es un error de resolución. Ver STXT-DISCOVERY-SPEC §3 y §4.

Escribir la gramática

La plantilla del libro es como la del tutorial, con el ISBN obligatorio y al menos un capítulo. Se puede escribir directamente en .stxt/ con cualquier nombre, o instalarla con stxt install, que comprueba que valida contra su meta-esquema y la escribe, en forma canónica, como .stxt/@stxt.template/<namespace>.stxt. Esa disposición es una convención de la CLI; el lenguaje no la impone.

Template (@stxt.template): com.acme.book
	Structure >>
		Book:
			Title: (1)
			Authors: (1)
				Author: (+)
			ISBN: (1)
			Publisher: (?)
			Published: (?) DATE
			Summary: (?) TEXT
			Chapter: (+)
				Content: (?) TEXT
	Description >>
		Book: Plantilla para fichas de libros editoriales
stxt install book-template.stxt

Installed com.acme.book (@stxt.template) to /home/ana/libros/.stxt/@stxt.template/com.acme.book.stxt

stxt schemas muestra la cadena de resolución de un directorio y, para cada namespace, la definición activa y su fichero:

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

Si el proyecto está dentro de otro que también tiene .stxt/, la cadena incluye los dos directorios, y para cada namespace gana el más cercano al documento.

Escribir y validar el documento

El documento, en docs/book.stxt, con el namespace de la plantilla:

Book (com.acme.book):
	Title: Arquitectura de software moderna
	Authors:
		Author: María Pérez
		Author: Juan García
	ISBN: 978-84-123456-7-8
	Published: 2025-10-01
	Summary: Una introducción práctica a la arquitectura de sistemas modernos.
	Chapter: Introducción
		Content >>
			Conceptos básicos y objetivos del libro.
stxt validate docs/book.stxt

No escribe nada y termina con código 0. Con Published cambiado a texto libre y sin la línea ISBN:

Book (com.acme.book):
	Title: Arquitectura de software moderna
	Authors:
		Author: María Pérez
		Author: Juan García
	Published: 1 de octubre de 2025
	Summary: Una introducción práctica a la arquitectura de sistemas modernos.
	Chapter: Introducción
		Content >>
			Conceptos básicos y objetivos del libro.
# ERROR: la fecha no es YYYY-MM-DD y falta ISBN, que es 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 hallazgo es fichero:línea: [CÓDIGO] mensaje (severidad). El código es estable y es el mismo en la CLI, en la extensión y en las tres bibliotecas. Un error de cardinalidad se señala en la línea del padre (Book, línea 1).

El código de salida es 1 si los documentos tienen errores y 2 si el comando se ha usado mal. Opciones de validate:

  • --warn-schema: los errores de gramática se reportan como avisos y no hacen fallar; los de sintaxis, sí.
  • --no-schema: solo sintaxis, sin buscar ni aplicar gramáticas.
  • --format json: los mismos hallazgos como array JSON.
  • --recursive (-r): valida directorios enteros; los .stxt/ que encuentra se omiten, porque no son documentos.

El resto está en la referencia de la línea de comandos.

Lo mismo desde VS Code

Con la carpeta libros/ abierta y la extensión instalada (code --install-extension stxt-lang.stxt) no hay nada que configurar. La extensión sigue la misma cadena de resolución que la CLI, también por encima de la raíz del workspace, y emite los mismos códigos. Con docs/book.stxt abierto:

  • Los errores de sintaxis aparecen como errores y los de gramática como avisos, con el mismo código y mensaje que en la línea de comandos.
  • Autocompletado (Ctrl+Espacio): dentro de Book propone solo los hijos que la plantilla permite; en un ENUM, sus valores.
  • Hover sobre un nombre de nodo: la descripción que dé la plantilla, su tipo y, si es un ENUM, sus valores.
  • Ir a la definición (F12) sobre Published abre .stxt/@stxt.template/com.acme.book.stxt en la línea Published: (?) DATE.
  • Formatear documento: reindenta y normaliza sin perder comentarios ni líneas en blanco.

Al editar la plantilla, la extensión vuelve a resolver y revalida los documentos abiertos. Un namespace que ninguna gramática de la cadena define se marca con SCHEMA_NOT_FOUND como aviso. El ajuste stxt.schemaValidation desactiva la validación con gramáticas, como --no-schema en la CLI.

Más de un nivel: usuario y sistema

El .stxt/ del proyecto es el primer nivel de la cadena; hay dos más:

Nivel Dónde stxt install ... Para qué
Proyecto .stxt/ del documento y de sus ancestros --local Las gramáticas del proyecto, versionadas con él
Usuario ~/.stxt (%USERPROFILE%\.stxt) --user Definiciones personales, comunes a todos los proyectos del usuario
Sistema /etc/stxt (%ProgramData%\stxt) --system Definiciones que una organización distribuye a toda una máquina

La precedencia es por namespace: para cada uno manda el nivel más cercano que lo defina, y los demás niveles aportan los namespaces que ese no define. Un proyecto puede llevar su com.acme.book y el usuario tener en ~/.stxt una plantilla org.ana.notas, y las dos aplican en la misma validación.

No se permiten dos definiciones del mismo namespace en el mismo nivel. Si la plantilla del libro se copia a .stxt/otro/copia.stxt, el namespace queda sin definición activa hasta que se retire una de las dos:

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

stxt validate reporta ese mismo error (línea 0, con el fichero causante) y falla. Ver STXT-DISCOVERY-SPEC §5 y §8.

Integración continua y STXT_PATH

La variable de entorno STXT_PATH sustituye la cadena de resolución entera por una lista de directorios (separados por :, o ; en Windows), en orden de precedencia; las entradas no tienen por qué llamarse .stxt. En un trabajo de CI evita que el resultado dependa del ~/.stxt o del /etc/stxt de la máquina:

STXT_PATH=./.stxt npx @stxt-lang/cli validate --recursive docs/
npx @stxt-lang/cli format --check --recursive docs/

format --check no escribe nada: lista los ficheros que cambiarían y falla si hay alguno, como gofmt -l o prettier --check. Reformatear requiere --write.

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. Una entrada que no existe no aporta nada y no es un error. Ver STXT-DISCOVERY-SPEC §6.

Sin instalar nada: el playground

En el playground no hay sistema de ficheros ni cadena de directorios: documentos y gramáticas se asocian por namespace dentro del workspace. Toda plantilla o esquema del workspace participa en la validación, y dos gramáticas con el mismo namespace son un error, como en un nivel de la cadena.

El botón Abrir en el playground del documento de esta página lo carga junto con su plantilla: al alterar la fecha o eliminar el ISBN, el panel de problemas muestra los mismos códigos que la CLI. El autocompletado, el hover y el interruptor de tabuladores/espacios funcionan como en la extensión, y Share copia una URL que contiene el workspace entero.