Los agentes del ciclo reactivo (constructor, executor, recopilador,
analizador, mejorador, orquestador) corrian con model: sonnet. Se suben
todos a model: opus para mejorar la calidad del codigo generado y del
razonamiento durante el ciclo CONSTRUIR -> EJECUTAR -> RECOPILAR ->
ANALIZAR -> MEJORAR.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Antes --color solo escribía los campos de color en Local State (info_cache), que
únicamente tiñen el círculo del avatar en el selector de perfiles. Ahora --color
aplica además el tema del navegador (toolbar, frame/bordes, barra de pestañas y
omnibox), que es lo que permite identificar un perfil de un vistazo.
El tema vive en el Preferences del perfil, no en Local State. La función ahora
escribe browser.theme.user_color2 (SkColor ARGB con signo), browser_color_variant
y is_grayscale2, y fuerza extensions.theme.system_theme=0. Escribe también las
claves legacy sin sufijo "2" por compatibilidad de versiones. Nuevo flag
--variant <0..4> (default 3 vibrant) para la intensidad del tinte. Backup y
validación del Preferences con el mismo patrón que Local State.
Claves verificadas empíricamente con captura de pantalla en Chromium 148: un
perfil lanzado con estas claves muestra la toolbar y el frame teñidos del color.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Nueva función Bash del dominio browser para personalizar la apariencia de un
perfil Chrome/Chromium y diferenciarlo de un vistazo. Edita
`profile.info_cache.<perfil>` en el Local State del user-data-dir:
- `--avatar <N>`: avatar built-in de Chrome (índice 0..55) vía
`avatar_icon = chrome://theme/IDR_PROFILE_AVATAR_<N>`. Camino robusto.
- `--avatar <ruta.png>`: avatar custom best-effort (copia la imagen al perfil y
marca `is_using_default_avatar=false`); ver gotchas del .md.
- `--color <#rrggbb>`: color del perfil. Convierte el hex a int32 con signo en
formato ARGB (0xAARRGGBB) y lo aplica a `profile_highlight_color`,
`profile_color_seed` y `default_avatar_fill_color`.
Sigue el patrón de create/delete_chrome_profile: backup del Local State antes de
escribir, validación del JSON resultante con restauración del backup si queda
inválido, guard de SingletonLock (chromium debe estar cerrado), idempotente y
con --dry-run. No crea perfiles (eso es create_chrome_profile); requiere que el
perfil ya exista. Probada con --avatar 26 --color #1f6feb y casos edge.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bug descubierto al ejecutar el reset real: los guards y los kills usaban
'pgrep -af [c]hromium | grep -F <udd>'. Como la ruta del user-data-dir contiene
la cadena 'chromium' (~/.config/chromium-cdp), el propio proceso grep/ugrep —cuyo
cmdline incluye <udd>— era capturado por pgrep, dando un falso positivo perpetuo:
el guard creía siempre que había un chromium abierto y delete/restore abortaban
con exit 2, y el lazo de cierre nunca convergía.
Fix en delete_chrome_profile, restore_chrome_bookmarks, create_chrome_profile y el
pipeline reset_chrome_profiles: enumerar por PID con 'pgrep -x chromium' (comm
exactamente 'chromium', nunca grep/pgrep/bash) y leer /proc/PID/cmdline para
comprobar el udd. Validado: reset destructivo real de los 4 perfiles completó OK,
cada perfil quedó con solo uBlock + web_proxy y los bookmarks restaurados.
Cinco funciones nuevas (dominio browser, grupo navegator) que cierran los gaps
de gestión de perfiles, más un pipeline que las orquesta:
- backup_chrome_bookmarks / restore_chrome_bookmarks: backup y restore de los
archivos Bookmarks (copia byte a byte verbatim para preservar el checksum
interno; en Chromium 148 los bookmarks no están bajo el super_mac de Secure
Preferences). Guard por user-data-dir (no global).
- delete_chrome_profile: borra la carpeta del perfil + limpia su entrada en
Local State (info_cache, profiles_order, last_active_profiles, last_used).
- create_chrome_profile: lanza chromium headless (vía systemd-run) para que la
managed policy instale la whitelist de extensiones, y asigna el nombre legible
en Local State. Mata todo el árbol de chromium del udd antes de editar Local
State (los hijos zygote/gpu no repiten --user-data-dir pero referencian la ruta).
- list_chrome_profile_extensions (Go): lista extensiones de un perfil con
ID/name/version/location/enabled/fromPolicy. 7 unit tests.
- reset_chrome_profiles (pipeline): backup -> cerrar chromium -> delete -> create
-> restore -> verify. Destructivo (--yes), --dry-run seguro.
Validado: unit tests Go verdes, backup/restore byte-idéntico, delete limpia Local
State, create instala la forcelist global (uBlock + web_proxy) en perfiles nuevos.
Cada projects/<name>/ es ahora su propio repo Gitea con branch master,
versionando solo sus docs de nivel-project. apps/*/ y analysis/*/ siguen
como sub-repos hijos independientes (excluidos por el .gitignore del project).
/full-git-push|pull los manejan via discover_git_repos. Cierra el gap de
docs de nivel-project sin versionar. Aplicado a web_scraping, fn_monitoring,
message_bus.
Permite force-instalar extensiones self-hosted bajo managed policy indicando
un update_url propio (p.ej. file:// a un update.xml local que apunta a un .crx).
Necesario para cargar extensiones propias (como la de captura de web_proxy)
cuando hay una managed policy activa y --load-extension queda desactivado en
Chromium 137+. Forma simple '<id>' sigue usando el update_url por defecto.
Rediseño de apply_chromium_extension_policy y nueva función de purga in-place,
tras resolver por qué las extensiones bloqueadas reaparecían en Chromium 148.
- apply_chromium_extension_policy: añade --block (ExtensionInstallBlocklist).
Reemplaza el modo ExtensionSettings "*": blocked (que rompía las extensiones
unpacked vía --load-extension, p.ej. la de captura de web_proxy con el error
'Loading of unpacked extensions is disabled by the administrator') por una
blocklist específica. FIX RAÍZ: los backups se guardan fuera de policies/managed/
(en policy-backups/), porque Chromium lee TODOS los archivos del directorio
managed/ sin filtrar extensión de nombre — un extensions.json.bak ahí se mergea
con la policy y reinyecta las extensiones del backup (location=7).
- clean_chrome_profile_extensions (nueva): purga in-place de un perfil existente
(borra carpetas de Extensions/ + refs en Preferences/Secure Preferences) dejando
solo la whitelist. Complementa la policy: la policy evita reinstalación, esta
desinstala lo ya presente. Requiere chromium cerrado.
Ambas: dominio browser, grupo navegator, guard de auto-ejecución, dry-run.
Cierra el gap de reproducibilidad entre PCs del proyecto web_scraping:
la organizacion de extensiones y el CDP global dejaban de ser pasos
manuales con sudo documentados en prosa.
- apply_chromium_extension_policy: escribe ExtensionInstallForcelist
(whitelist via --keep) en /etc/chromium/policies/managed/extensions.json
de forma idempotente, con backup automatico y validacion JSON. --dry-run
previsualiza sin tocar el sistema.
- apply_chromium_cdp_flag: gestiona /etc/chromium.d/cdp (CDP global).
Loopback por defecto, --network para bind 0.0.0.0 (con aviso), --remove
para desactivar, --dry-run para previsualizar. Idempotente con backup.
Ambas: dominio browser, grupo navegator, impuras (escriben en /etc via
sudo), guard de auto-ejecucion (ejecutables con fn run y sourceables).
Docs del proyecto (CONVENTIONS.md reglas 8/9, CHROMIUM_SYSTEM.md
inventario + tabla accionable) ahora apuntan a 'fn run apply_chromium_*'
como metodo canonico en vez de editar los archivos de /etc a mano.
Funciones nuevas del dominio browser (grupo navegator):
- cdp_move_mouse_human / cdp_click_human: movimiento de raton con curva
de Bezier cubica, easing y micro-jitter para imitar comportamiento
humano y reducir deteccion de automatizacion.
- cdp_wait_idle: espera network-idle contando requests en vuelo via
eventos CDP Network.*; inmune a extensiones que mutan el DOM
(Dark Reader, uBlock) y a animaciones JS.
- list_chrome_profiles: lista perfiles de un user-data-dir (extensiones,
nombre legible, preferencias).
- prepare_chrome_profile (bash): clona un user-data-dir conservando solo
una whitelist de extensiones (default uBlock Origin Lite).
Modificadas:
- chrome_launch: Linux-first (chromium/google-chrome/brave antes que
chrome.exe), KeepExtensions y Setpgid para matar el arbol con cdp_close.
- cdp_close: kill por grupo de proceso.
Todas con tests verdes (go test ./functions/browser ok).
Design system Compose (kotlin/functions/ui, modulo Gradle `fn.compose:ui`):
- FnTokens + FnTheme con la paleta heredada al hex de cpp/DESIGN_SYSTEM.md
(Mantine v9 dark + indigo), identica a la web @fn_library y a las apps C++.
- 26 componentes Compose (Layout/Display/Inputs/Feedback/Data/Charts) +
FnTheme + FnTokens registrados en el registry (28 entradas kind=component
lang=kt domain=ui), descubribles via fn_search. Habilitan init_kotlin_app.
Recuperacion: el commit cb6d9e6 habia anadido `kotlin/functions/ui/` al
.gitignore, por eso el design system nunca se versiono y se perdio del working
tree. Des-ignorado; el .gitignore interno del modulo ya excluye
build/.gradle/local.properties. La gallery (apps/gallery_kt) se recupero del
sub-repo Gitea y sus 27 componentes se reconstruyeron con su MainActivity como
contrato exacto.
Toolbelt Android Linux-first (antes asumia WSL2 + Windows):
- adb_wsl 1.1.0, android_emulator_start 1.1.0, android_emulator_list 1.1.0:
resuelven adb/emulator nativos del SDK ($ANDROID_HOME), .exe solo fallback WSL2.
- android_emulator_start: fix `timeout adb_run wait-for-device` (timeout no puede
ejecutar una funcion del shell; ahora invoca el binario $ADB directamente).
- install_android_sdk 1.0.1: fix licencias bajo pipefail (SIGPIPE de `yes`) +
trap EXIT con variable unbound.
- docs/capabilities/android.md regenerado Linux-first + seccion design system.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El .mcp.json generado ahora apunta al wrapper jupyter_mcp_serve.sh con env overrides
(JUPYTER_MCP_VENV/ROOT/PORT/TOKEN) en vez del console-script jupyter-mcp-server directo.
Antes: el .mcp.json solo CONECTABA a un Jupyter ya existente y, si se abria Claude
desde la raiz del repo, el MCP usaba el venv canonico python/.venv (sin las deps del
analisis). Ahora el wrapper arranca (o reusa) un Jupyter con el venv del propio
analisis, asi que abrir Claude desde el directorio del analisis basta y cada analisis
ejecuta con sus dependencias sin contaminar python/.venv.
Bump v1.2.0. Declara dependencia jupyter_mcp_serve_bash_infra.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
DagContinueOn gana el campo ExitCodes []int (codigos de salida tolerados) y el
parser mapea continue_on.exit_code desde el YAML. retry_policy (limit,
interval_sec) ya existia en el modelo y ahora queda documentado como contrato
estable para los executors.
Funcion pura: solo normaliza el YAML al modelo DagDefinition; la interpretacion
(reintentar, tolerar codigos) vive en el executor que lo consuma (dag_engine).
Test: 'parsea continue_on.exit_code y retry_policy'. Tag de grupo: scheduler.
Marca todos los submodulos de cpp/vendor (y emsdk) como shallow en .gitmodules
para que los clones futuros descarguen solo el commit pinneado en vez de toda la
historia upstream. Reduce .git/modules de ~338MB a ~35MB sin perder codigo: el
working tree mantiene el snapshot completo de cada dependencia. Reversible por
submodulo con 'git fetch --unshallow'.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Funcion pura que describe expresiones cron en lenguaje natural estilo
crontab.guru (consumida por el tooltip de schedule del frontend de dag_engine
via /api/cron/describe). Tambien se anade build/ (raiz) al .gitignore para que
los artefactos de compilacion C++ no se vuelvan a versionar.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mueve duckdb_open, clickhouse_open, postgres_open, matrix_* y keyring_token_store
del paquete monolitico functions/infra a subpaquetes propios
(functions/infra/{duckdb,clickhouse,postgres,matrix,keyring}). El paquete infra ya
no importa los drivers (go-duckdb, clickhouse-go, pgx, mautrix, go-keyring), por lo
que las apps que solo usan funciones ligeras (process, cron, http, sqlite) dejan de
arrastrarlos. Reduccion de binarios: dag_engine 72->10MB, registry_api 70->8.7MB,
services_api 70->9MB, call_monitor 68->6.6MB, sqlite_api 70->8.9MB.
Los IDs del registry se mantienen estables (domain: infra en frontmatter). Se
preservan los build tags goolm/libolm de matrix_crypto_init.
Tambien corrige TestSSEHandler: el test leia el body con un unico Read() que con
HTTP chunked solo capturaba el primer evento; ahora usa io.ReadAll hasta EOF.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reconstruye el cableado de hooks del bucle reactivo (issues 0085-0087), que no
viajaba entre PCs por no estar versionado:
- PostToolUse: hook_call_monitor (capturador de calls/code_writes/violations)
+ hook_capability_tag_gate.
- PreToolUse: hook_registry_mcp (aviso sqlite3 directo) + hook_fn_match.
- UserPromptSubmit: hook_capabilities_inject + hook_registry_first_reminder.
Rutas via $CLAUDE_PROJECT_DIR para portabilidad entre maquinas.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Los headers usaban uint8_t/uint32_t en enum-base-types (ColorRuleKind,
CellRenderer, TableEventKind) y en StringPool sin incluir <cstdint>/<cstddef>.
MSVC los arrastra transitivamente; GCC no, lo que rompia la compilacion del
modulo data_table y de toda app que lo enlaza (registry_dashboard, etc.) en
Linux nativo. Una sola cabecera afectada; el resto los obtiene transitivamente.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
full_git_push: el auto-recover de non-fast-forward nunca se disparaba por dos
bugs. (1) git_push_if_ahead hacia `tail -1` del error de push y se quedaba con
la linea final de `hint:`, perdiendo "[rejected]" y "Updates were rejected", de
modo que el pipeline no detectaba el rechazo. Ahora se preservan las lineas con
los keywords (rejected/fast-forward/fetch first). (2) El paso 4 capturaba stdout
y stderr juntos (2>&1), metiendo lineas "[push]" de stderr al principio del
status y rompiendo el glob `== "[error]"*` anclado al inicio; ahora solo captura
stdout y la deteccion cubre todas las redacciones de git. (3) El merge auto
evaluaba el exit de `tail` (siempre 0) en vez del de `git merge`; un merge con
conflictos se reportaba como exito. Ahora se evalua el exit real del merge y se
aborta limpio ante conflictos.
Limpieza: cpp/apps/chart_demo y cpp/apps/shaders_lab estaban commiteados como
gitlinks (submodulos, mode 160000) sin URL en .gitmodules, directorios vacios
fantasma que rompian el paso 3 de full_git_pull con "fatal: No url found for
submodule path". Eliminados del indice. Las apps C++ reales viven en apps/ como
sub-repos Gitea independientes (regla cpp_apps.md; cpp/apps/ deprecado por
issue 0096).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Auto-init step skipped any dir with .git present, even when it lacked
an origin remote. Such dirs fell through to push step and failed with
"'origin' does not appear to be a git repository". Now skip only when
.git AND origin exist; otherwise run ensure_repo_synced to create the
Gitea repo + add origin + push.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Foundation (ce7470d5) + reader rewire (2f7fdd40).
- ColumnSnapshot per col (i64/f64/str_ids) + StringPool per-State
- compute_visible_rows filter/sort uses snapshot direct numeric/id compare
- StringPool realloc-crash fix (reserve before emplace_back)
- Pool staleness sentinel (rebuild when string_pool.size() drift)
- High-cardinality cap (>2048 unique → skip interning, fallback raw)
API publica intacta. Bench 100k sort_numeric +131% vs baseline.
text_editor_smoke RED preexisting unrelated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Change 3 of issue 0133 — rewire compute_visible_rows, filter eval,
and sort comparators to read from the SnapshotCache when available.
Hot paths rewired:
- compute_visible_rows (overload with snap): filter eval uses
compare_snap (fast i64/f64 numeric compare for Int/Float cols;
id-compare for low-cardinality string Eq/Neq; raw cells fallback
for Contains/StartsWith/EndsWith).
- Sort comparators: direct i64/f64 array compare for Int/Float cols
(goto sort_done skips string fallback); string sort uses uint32_t
id compare with pool lookup only on mismatch.
- Stage>0 filter/sort: same snapshot overload.
Materialization paths (build_so, s0_backing, mat_backing, config popup)
kept on raw cells — they copy into std::string anyway, no benefit from
snapshot and snprintf-per-cell was 2M extra calls per frame.
Bug fixes (required for correctness):
1. StringPool::intern() realloc safety: force reserve before
emplace_back so string_view keys in the map never go dangling.
2. SnapshotCache::pool_size_built sentinel: detects when a new State
is created with an empty pool but same cells pointer (begin_scenario
pattern). Prevents str_ids from indexing into an empty pool (SIGSEGV).
3. Cardinality cap (2048 uniques / 25% sample): high-cardinality string
cols (timestamps-as-strings, UUIDs, names) skip interning — str_ids
stays empty and compare_snap falls back to raw cells. Prevents 30MB+
pool bloat that hurt cache for filter/sort on other cols.
Bench delta vs baseline (100k rows, LIBGL_ALWAYS_SOFTWARE=1):
linear_scroll: 16.0 -> 15.5 fps p50 (-3%, baseline already FAIL)
filter_like: 59.7 -> 56.0 fps p50 (-6%, still PASS at 56fps)
sort_numeric: 3.9 -> 9.0 fps p50 (+131%, snapshot i64 sort)
color_rule: 15.2 -> 14.8 fps p50 (-3%, baseline already FAIL)
Build: green for all 10 available Linux consumers (text_editor_smoke
linker failure is preexisting, not caused by this change).
API public intact. TableEvent.row indexing TableInput preserved.
Pointer-identity invalidation preserved.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>