Un solo archivo deja de alcanzar apenas quieres pruebas, dependencias o un binario que puedas copiar a otro lado. Un proyecto te da las tres cosas, y está a un comando de distancia.
nyx init
$ nyx init my-app nyx v0.31.0 — init CAPABILITIES.md generado desde ~/.nyx/std (59 archivos escaneados) Initialized project: my-app Created: my-app/ Next: cd my-app && nyx run
Eso siembra nueve archivos:
my-app/ nyx.toml .gitignore src/main.nx AGENTS.md CAPABILITIES.md docs/nyx/LLM.md docs/nyx/guides/write-a-program.md docs/nyx/guides/fix-a-compile-error.md docs/nyx/guides/report-friction.md
Los primeros tres son el proyecto. Los otros seis son el contexto que un asistente necesita para escribir Nyx acá sin adivinar — el paso 04 trata sobre ellos. Si quieres los documentos en español, nyx init my-app --lang es siembra el juego en español; --agent= y --sdd agregan más, y el paso 04 cubre los dos.
nyx.toml
[package] name = "my-app" version = "0.1.0" main = "src/main.nx" [dependencies]
name es además el nombre del binario que produce nyx build, y la línea que el .gitignore sembrado ya ignora. main es el punto de entrada al que vuelve cada herramienta cuando no le das un archivo.
Compilar y ejecutar
$ nyx build nyx v0.31.0 — build -> building my-app v0.1.0 compiling src/main.nx ✓ Built: my-app build complete
Eso deja ./my-app al lado de nyx.toml: un ejecutable nativo que puedes copiar a otra máquina de la misma arquitectura. nyx run hace el mismo build y después lo ejecuta.
Los argumentos después de nyx run van a tu programa, no a Nyx. Cuando un argumento se podría confundir con una bandera, antepón --:
fn main() { let args: Array = get_args() var i: int = 0 while i < args.length() { let a: String = args[i] print(int_to_string(i) + ": " + a) i = i + 1 } }
$ nyx run -- --verbose one nyx v0.31.0 — run -> building my-app v0.1.0 compiling src/main.nx ✓ Built: my-app 0: ./my-app 1: --verbose 2: one
El elemento 0 es la ruta del binario, así que tus argumentos empiezan en 1. Fíjate en la anotación de tipo de a: un elemento leído de un Array sin anotarlo se trata como int, e imprimirlo te da un número en vez del texto.
Pruebas
nyx test corre todos los tests/*.nx. Una prueba es un bloque test "nombre" { … } — no una función:
test "greeting is not empty" { let msg: String = "hello" assert(msg.length() > 0) } test "sum works" { assert(1 + 1 == 2) }
$ nyx test === Nyx Test Runner === Found 1 test file(s) PASS tests/greet_test.nx (2 tests) =================================== Files: 1 passed, 0 failed (1 total) Tests: 2 passed, 0 failed (2 total) Status: ALL TESTS PASSED ===================================
La trampa que conviene conocer antes de pisarla. Un archivo lleno de funciones llamadas test_algo() se encuentra, se cuenta, y después se saltea — el corredor dice No files with test blocks found y sale contento. Nada falló, porque nada corrió. Si tu conteo de pruebas es cero y esperabas pruebas, es por esto: los bloques son test "nombre" { … }, siempre.
Ten en cuenta también que assert() aborta el proceso en el primer fallo. Dentro de nyx test eso está resuelto — reporta por prueba y sale al final — pero en un programa tuyo, una aserción que falla es el final del programa.
Dependencias
$ nyx add some-package $ nyx add some-package --from https://example.com/some-package.git
La dependencia se escribe en [dependencies] dentro de nyx.toml, y nyx build clona lo que falte en packages/ — que el .gitignore sembrado ignora, asumiendo que prefieres traerlas a vendorizarlas. Borrar esa línea y commitear packages/ es la otra decisión razonable: hace el build reproducible sin red.
La biblioteca estándar no necesita nada de esto. Módulos como std/json, std/http o std/toml vienen con la toolchain y se usan con un import "std/json" y nada más.
Dos comandos que vas a querer después
$ nyx info nyx v0.31.0 — info Project: my-app Version: 0.1.0 Main: src/main.nx Mode: GC (default)
Y, después de actualizar la toolchain, nyx update --sync-docs — corrido dentro del proyecto — refresca los documentos sembrados a la versión que tienes ahora, guardando un .bak de todo lo que reemplaza. Qué refresca, y por qué importa, es el paso siguiente.