Bloque de cambios revisados y validados con el usuario en sesiones
previas que no habian aterrizado en commits propios. Lista por tema:
* enrichers: web_search ahora usa lite.duckduckgo.com como endpoint
primario (mas tolerante con bot detection desde IP residencial),
con fallback al endpoint html. Detecta pagina captcha y emite
error claro si ambos fallan. Anyade _DDGLiteParser para el formato
lite + auto-pick de parser por contenido.
* enrichers: tipo Webpage unificado en Url (campos de cuerpo
cacheado viven en metadata del Url). Manifests actualizados
(applies_to: [Url]). fetch_webpage ya no convierte Url->Webpage.
* enrichers/manifest: campo `params` parseado a EnricherSpec.params
(name, type, default_value, description). UI puede renderizar
dialog de configuracion.
* jobs: fix de path conversion para Python embebido nativo Windows
(no convertir a /mnt/c/... cuando el subproceso es Windows-native;
solo cuando es bash o python via WSL).
* main.cpp: ventana ImGui (no modal) "Run enricher" con layout
2-col (label izq, input der). Inserta job con JSON tipado. Layout
clustering apretado: hijos del mismo anchor en un solo anillo
alrededor del padre, sin desperdigar por anillos crecientes.
* views: inspector con layout 2-col via BeginTable (Identity,
Schema fields, Extras). Description full-width debajo de su label.
* tests: portable conftest (auto-detecta REGISTRY_ROOT, PYTHON_BIN,
ENRICHERS_DIR para WSL y Windows portable). _runner.py trampoline
inyecta stub via sys.path porque embedded Python ignora PYTHONPATH.
Tests bash-only (vendor_script, freeze, dispatcher bash, resolver
Linux-binary) skipean en Windows. Tests existentes adaptados a
Webpage->Url.
Resultado actual: 32 passed WSL, 21 passed + 11 skipped Windows.
Extiende el sistema de enrichers para soportar varios lenguajes en el
mismo registro. El manifest gana dos campos opcionales:
lang: python|go|bash (default: python — retrocompat con los 5
enrichers existentes que no lo declaran)
exec: run (basename del script o binario; default "run")
EnricherSpec ahora lleva `lang`, `exec_basename`, `disabled` y
`disabled_reason`. parse_manifest lee los nuevos campos y aplica
defaults; resolve_run_path busca <dir>/<exec>{.py|.sh|.exe|<vacio>}
segun lang + plataforma. Si el ejecutable no existe (binario Go sin
compilar, script ausente), el spec queda en el registro pero
disabled — enrichers_for_type lo oculta del menu y jobs.cpp aborta
con mensaje claro si llega un job para uno disabled.
run_subprocess (POSIX y Windows) ramifica argv segun lang:
- go -> execv del binario directamente, sin python ni wsl.exe
- bash -> /bin/bash <run_path> (en Windows: wsl.exe -- bash ...)
- python -> python3 <run_path> (default)
El call site en jobs.cpp resuelve run_path y lang via
ge::enricher_by_id() en lugar del hardcode "run.py". Los 5 enrichers
existentes siguen funcionando sin cambios — heredan lang: python por
default.
Tests pytest (22/22 verde):
- 16 regresion: los 5 enrichers actuales siguen pasando.
- 6 nuevos en test_dispatcher_lang.py: parser default a python,
parser lee lang: bash, wire protocol identico para python y
bash, enricher Go sin binario queda disabled, enricher real
sigue funcionando tras el cambio.
NO incluye: runtime Python embebido (fase B) ni badges de lang en
la UI (fase C). El issue 0033 sigue abierto hasta cerrar las dos
fases restantes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>