NightScribe: desarrollar
Este es el camino corto para quien mantiene el proyecto: cómo ejecutarlo y las tres recetas que más salen (una fuente de datos nueva, un tipo de objetivo nuevo, una pestaña nueva del editor). Las reglas están en AGENTS.md; las decisiones, en docs/adr/.
Ejecutarlo
python3 -m venv --system-site-packages .venv
.venv/bin/pip install -r requirements.txt -r requirements-dev.txt
.venv/bin/python -m pytest tests/unit -n auto --dist loadfile # rápido, sin red
.venv/bin/python -m pytest tests/functional # con red
.venv/bin/python -m nightscribe guiLa suite unitaria es offline a propósito: una llamada a requests lanza, y el fallback propio de la fuente tiene que gestionarlo. Además acota sus propios pools de hilos (el combine). En una máquina con muchos núcleos, -n auto puede hacer que un worker muera de vez en cuando (un crash nativo que no hemos localizado); -n 4, o PYTEST_XDIST_AUTO_NUM_WORKERS=4, es más estable. El CI, con 2-4 núcleos, no se ve afectado.
Las reglas que son tests
Algunas reglas de la casa las sostiene un test, para que una PR falle a voces en vez de en silencio: test_help_texts.py (una ayuda no nombra el caso concreto), test_em_dash.py (ni en la guía ni en las cadenas de la interfaz), test_import_boundaries.py (requests solo en core/sources/, nada de SQLite en la GUI), test_docs_links.py (todo enlace de la documentación resuelve, el índice de ADR está completo), test_site_build.py (la web commiteada es la que produce el generador), test_i18n.py (los dos catálogos completos y en sincronía) y test_kinds_contract.py (cada tipo tiene color, chip, análisis, campos de contexto y hashtags).
Receta: una fuente de datos nueva
Un módulo por fuente,
nightscribe/core/sources/<nombre>.py. Expone una funciónfetch(...)/cliente pequeña y nunca llama arequestsdirectamente: pasa por la caché,db.http_get(key, "<fuente>", fetch), así que el TTL y el comportamiento offline no son su problema.Registra el TTL en
core/db.py(SOURCE_TTL). Elígelo por cada cuánto cambia de verdad lo de arriba (un atlas estático son 30 días, una lista de descubrimientos son horas).Conéctala:
core/planner.pysi alimenta Esta noche (añade una etapa a la listastagesy una fase aPHASES),core/enrich.pysi es contexto para la ficha del objeto.Documéntala en
docs/DATA_SOURCES.md(el endpoint, qué da, el TTL, si necesita clave) y añádela a la lista de fuentes del cuadro Acerca de.Pruébala: un test unitario con la fuente simulada (la suite es offline) y un test funcional que pegue al endpoint real.
Receta: un tipo de objetivo nuevo
Un tipo es un id de texto escrito a mano en muchos sitios, así que esto es una cacería. Empieza en core/kinds.py (la lista canónica KINDS, más ANALYSIS y _CONTEXT_FIELDS), y luego:
gui/theme.py:KIND_COLORSyKIND_LABELS(el chip);core/planner.py: un constructor y su fase;core/suggest.py: cómo puntúa y su «por qué esta noche»;core/narrative.py: el gancho y los hashtags;gui/overview.py: las filas de la ficha del objeto para el tipo;core/project.py:VALID_KINDSsi puede ser un proyecto.
test_kinds_contract.py falla hasta que los mapas cubren el id nuevo, que es la red de seguridad barata; las cadenas de if las tienes que encontrar tú. Añade los tests del tipo y, si trae una fuente, su entrada en DATA_SOURCES.md.
Receta: una pestaña nueva del editor (UFE)
Las pestañas del editor FITS unificado siguen el ADR-005: la interfaz es un fichero de Designer, el código la cablea.
La estructura en
nightscribe/gui/ui/ufe_<nombre>_tab.ui: cada texto y tooltip vive aquí, con<class>= la clase propietaria yobjectName= el atributo de Python.La pestaña en
nightscribe/gui/ufe_<nombre>_tab.py: carga el.uiconui_loader.load_ui, cablea las señales, rellena los datos. Los widgets propios (un canvas, un histograma) nunca entran al.ui: unQWidgetde relleno másreplaceWidget.Toda cadena visible por
self.tr(), y ejecutatools/i18n.py(nunca unlreleasecrudo).Regístrala en
gui/ufe_dialog.py(la barra de pestañas y el estado compartido,gui/ufe_state.py).Pruébala offscreen: monta la pestaña sobre una placa temporal y comprueba lo que muestra y lo que escribe.
Commitear
Código, comentarios y mensajes de commit en inglés; un asunto por commit; los tests en verde; la documentación (los dos idiomas) al día. Si cambias una decisión, actualiza o supera su ADR.