03 / 06

Proyectos

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.