feat: cierra issues 0050 y 0052 + commands automáticos
- 0050: jupyter_exec reescrito sin Y.js (REST + KernelClient). Bug raíz adicional: HEAD /api/contents da 405 → cambiado a GET. 9 tests (5 unit + 4 e2e). - 0052: footprint_aurgi cerrado. Bug fix en setup_geo_stack_docker_pipeline (verify aborta si compose up falla; nombre de contenedor incorrecto). - Nueva primitiva docker_container_running_py_infra (7 tests). - /full-git-push y /full-git-pull pasan a modo automático: auto-commit + push sin preguntar, aborta solo si detecta secrets. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
# /full-git-pull — Pull de fn_registry + todos los sub-repos + submodules + fn sync
|
||||
# /full-git-pull — Pull automático de fn_registry + sub-repos + submodules + fn sync
|
||||
|
||||
Trae los últimos cambios del remote para el repo principal `fn_registry`, todos los sub-repos git anidados que **ya existan localmente**, y los submodules de `cpp/vendor/`. Después regenera `registry.db` y corre `fn sync` para tirar de la metadata del `registry_api` (apps, projects, analysis, vaults, pc_locations registrados desde otros PCs).
|
||||
Trae los últimos cambios del remote para el repo principal `fn_registry`, todos los sub-repos git anidados que **ya existan localmente**, y los submodules de `cpp/vendor/`. Después regenera `registry.db` y corre `fn sync` para tirar de la metadata del `registry_api`.
|
||||
|
||||
**No clona repos que falten.** Cada PC tiene solo el subset de apps/analyses que le interesa (ver memoria "Gitea = fuente de verdad; PCs subset"). Si en este PC necesitas un sub-repo que aún no tienes, clónalo a mano:
|
||||
**Modo automático (preferencia del usuario):** este comando NO pregunta. Auto-stashea dirty trees antes de pullear y hace `pop` después. Sigue con el resto de repos aunque uno falle. Solo se detiene si detecta riesgo serio (conflicto en stash pop que requiere intervención humana).
|
||||
|
||||
**No clona repos que falten.** Cada PC tiene solo el subset de apps/analyses que le interesa. Si en este PC necesitas un sub-repo que aún no tienes, clónalo a mano:
|
||||
|
||||
```bash
|
||||
git clone https://<user>:<token>@<gitea-host>/dataforge/<name>.git <path>
|
||||
@@ -19,21 +21,18 @@ Consulta `pc_locations` para ver dónde lo tiene otro PC y reproduce el path.
|
||||
### 1. Descubrir repos locales
|
||||
|
||||
```bash
|
||||
cd /home/lucas/fn_registry # ajustar al PC
|
||||
cd /home/lucas/fn_registry
|
||||
|
||||
REPOS=$(find . -name ".git" -type d \
|
||||
-not -path "./.git/*" \
|
||||
-not -path "*/node_modules/*" \
|
||||
-not -path "*/.venv/*" \
|
||||
-not -path "*/cpp/vendor/*" \
|
||||
-not -path "*/cpp/build/*" \
|
||||
-not -path "*/sources/*" \
|
||||
-not -path "*/temp/*" \
|
||||
-not -path "*/subrepos/*" 2>/dev/null | sed 's|/.git$||')
|
||||
-not -path "./.git" -not -path "./.git/*" \
|
||||
-not -path "*/node_modules/*" -not -path "*/.venv/*" \
|
||||
-not -path "*/cpp/vendor/*" -not -path "*/cpp/build/*" \
|
||||
-not -path "*/sources/*" -not -path "*/temp/*" -not -path "*/subrepos/*" 2>/dev/null \
|
||||
| sed 's|/.git$||')
|
||||
REPOS=". $REPOS"
|
||||
```
|
||||
|
||||
Solo se actualizan los sub-repos que ya tengan `.git/` localmente. Lo que falte se queda fuera — pull-on-demand por sub-repo.
|
||||
Solo se actualizan los sub-repos que ya tengan `.git/` localmente.
|
||||
|
||||
### 2. Para cada repo: stash si dirty, pull --ff-only, pop
|
||||
|
||||
@@ -56,8 +55,8 @@ for r in $REPOS; do
|
||||
done
|
||||
```
|
||||
|
||||
- Si `--ff-only` falla por divergencia, abortar el pull de ese repo y reportar (no rebasear sin permiso).
|
||||
- Si `stash pop` produce conflictos, **avisar** y dejar el conflicto al usuario; no resolverlo automáticamente.
|
||||
- Si `--ff-only` falla por divergencia → reportar ese repo, seguir con el resto. **No** rebasear ni mergear.
|
||||
- Si `stash pop` produce conflictos → **avisar al usuario al final** y dejar el conflicto sin tocar; seguir con los demás repos.
|
||||
|
||||
### 3. Submodules del repo principal
|
||||
|
||||
@@ -71,7 +70,7 @@ git submodule update --init --recursive 2>&1 | tail -10
|
||||
CGO_ENABLED=1 ./fn index 2>&1 | tail -3
|
||||
```
|
||||
|
||||
### 5. fn sync con credenciales de pass
|
||||
### 5. fn sync
|
||||
|
||||
```bash
|
||||
USER=$(pass registry/basicauth-user | head -1)
|
||||
@@ -82,14 +81,15 @@ export REGISTRY_API_TOKEN="$TOKEN"
|
||||
./fn sync
|
||||
```
|
||||
|
||||
Si `pass` falla → gpg-agent locked, pedir al usuario `pass show registry/api-token` en su terminal real.
|
||||
Si `pass` falla → gpg-agent bloqueado, pedir al usuario `pass show registry/api-token` en su terminal real.
|
||||
|
||||
### 6. Resumen
|
||||
|
||||
Tabla concisa: por repo, commits pulleados o "ya estaba al día"; submodules actualizados; result de `fn index`; result de `fn sync`.
|
||||
Tabla concisa: por repo, commits pulleados o "ya estaba al día"; submodules actualizados; resultado de `fn index`; resultado de `fn sync`. Si algún repo quedó con conflicto de stash o divergencia, listarlos al final con la acción sugerida.
|
||||
|
||||
## Notas
|
||||
|
||||
- **Modo no-interactivo por diseño.** El usuario prefiere flujos rápidos sin confirmaciones.
|
||||
- Pull solo es fast-forward — nunca rebase ni merge automático.
|
||||
- Si el repo principal pulleó cambios y eliminó archivos referenciados por sub-repos (raro), el usuario debe resolverlo manualmente.
|
||||
- Auto-stash incluye untracked (`--include-untracked`) para no perder archivos nuevos.
|
||||
- `fn index` se corre **antes** de `fn sync` para que las locations locales reflejen el estado actual.
|
||||
|
||||
@@ -1,33 +1,44 @@
|
||||
# /full-git-push — Push de fn_registry + todos los sub-repos + fn sync
|
||||
# /full-git-push — Push automático de fn_registry + todos los sub-repos + fn sync
|
||||
|
||||
Pushea el repo principal `fn_registry` y todos los sub-repos git anidados (apps y analyses, cada uno como repo independiente bajo `dataforge/<name>` en Gitea), y luego ejecuta `fn sync` para empujar la metadata no regenerable (proposals, apps, projects, analysis, vaults, pc_locations) al `registry_api`.
|
||||
|
||||
**Estandar:** todo `apps/<name>`, `analysis/<name>`, `projects/*/apps/<name>` y `projects/*/analysis/<name>` debe tener su propio repo Gitea bajo `dataforge/<basename>`. Los `subrepos/` de la raiz NO entran (son mirrors upstream que no se pushean desde aqui). Los `vaults/` tampoco — son datos puros con su propio mecanismo de compartir (TBD).
|
||||
**Estandar:** todo `apps/<name>`, `analysis/<name>`, `projects/*/apps/<name>` y `projects/*/analysis/<name>` debe tener su propio repo Gitea bajo `dataforge/<basename>`. Los `subrepos/` de la raiz NO entran (mirrors upstream). Los `vaults/` tampoco.
|
||||
|
||||
**Modo automático (preferencia del usuario):** este comando NO pregunta. Si hay dirty trees, commitea automáticamente con un mensaje generado a partir de los cambios. Prioridad: hacer commits frecuentes y pushear rápido. **Único límite:** no commitear archivos que parezcan secrets (`.env`, `*credentials*`, `*.key`, `*.pem`, `id_rsa*`) — si se detectan, abortar y avisar.
|
||||
|
||||
## Argumento
|
||||
|
||||
`$ARGUMENTS` — opcional. Si se pasa texto, se usa como mensaje de commit por defecto cuando algún repo tenga cambios sin commitear y el usuario apruebe commitear durante el flujo. Sin argumento, se pregunta el mensaje al detectar dirty tree.
|
||||
`$ARGUMENTS` — opcional. Si se pasa texto, se usa como mensaje de commit. Sin argumento, se genera uno automáticamente con el patrón:
|
||||
|
||||
```
|
||||
chore: auto-commit (<N> archivos modificados, <N> nuevos, <N> borrados)
|
||||
|
||||
- <ruta1>
|
||||
- <ruta2>
|
||||
...
|
||||
```
|
||||
|
||||
Si los cambios tienen un patrón claro (todos en un mismo dominio/dir), usar ese patrón en el subject:
|
||||
- todo bajo `python/functions/<dom>/` → `feat(<dom>): auto-commit con N cambios`
|
||||
- todo bajo `dev/issues/` → `chore(issues): auto-commit`
|
||||
- mezclado → `chore: auto-commit`
|
||||
|
||||
## Pasos
|
||||
|
||||
### 1. Descubrir repos git + apps/analyses sin git en el workspace
|
||||
### 1. Descubrir repos git + apps/analyses sin git
|
||||
|
||||
```bash
|
||||
cd /home/lucas/fn_registry # ajustar al PC
|
||||
cd /home/lucas/fn_registry
|
||||
|
||||
# 1a) Repos git ya existentes (sin subrepos/, sin cpp/vendor/, sin sources/, sin temp/)
|
||||
REPOS=$(find . -name ".git" -type d \
|
||||
-not -path "./.git/*" \
|
||||
-not -path "*/node_modules/*" \
|
||||
-not -path "*/.venv/*" \
|
||||
-not -path "*/cpp/vendor/*" \
|
||||
-not -path "*/cpp/build/*" \
|
||||
-not -path "*/sources/*" \
|
||||
-not -path "*/temp/*" \
|
||||
-not -path "*/subrepos/*" 2>/dev/null | sed 's|/.git$||')
|
||||
-not -path "./.git" -not -path "./.git/*" \
|
||||
-not -path "*/node_modules/*" -not -path "*/.venv/*" \
|
||||
-not -path "*/cpp/vendor/*" -not -path "*/cpp/build/*" \
|
||||
-not -path "*/sources/*" -not -path "*/temp/*" -not -path "*/subrepos/*" 2>/dev/null \
|
||||
| sed 's|/.git$||')
|
||||
REPOS=". $REPOS"
|
||||
|
||||
# 1b) Apps y analyses SIN .git — candidatos a inicializar
|
||||
# Apps/analyses sin .git — auto-inicializar como dataforge/<basename>
|
||||
MISSING=()
|
||||
for d in apps/*/ analysis/*/ projects/*/apps/*/ projects/*/analysis/*/; do
|
||||
d="${d%/}"
|
||||
@@ -35,11 +46,9 @@ for d in apps/*/ analysis/*/ projects/*/apps/*/ projects/*/analysis/*/; do
|
||||
done
|
||||
```
|
||||
|
||||
Si `MISSING` no esta vacio, listarlos al usuario y preguntar si inicializarlos como repos `dataforge/<basename>` antes de continuar (paso 1c).
|
||||
### 1b. Auto-inicializar repos faltantes (sin pedir confirmación)
|
||||
|
||||
### 1c. Inicializar repos faltantes (opcional, requiere confirmacion)
|
||||
|
||||
Para cada `$d` aprobado por el usuario:
|
||||
Para cada `$d` en `MISSING`:
|
||||
|
||||
```bash
|
||||
export GITEA_URL=$(pass agentes/gitea-url | head -n1)
|
||||
@@ -52,24 +61,45 @@ bash -c "
|
||||
"
|
||||
```
|
||||
|
||||
**Antes de inicializar**, comprobar que `$d/.gitignore` existe; si no, escribir uno apropiado (ver `.claude/rules/apps_vs_functions.md` para patrones tipicos: excluir `.venv/`, `node_modules/`, binarios, `operations.db*`, `.jupyter*`, `__pycache__/`).
|
||||
Si `$d/.gitignore` no existe antes de inicializar, escribir uno apropiado (ver `.claude/rules/apps_vs_functions.md`). Solo abortar la inicialización de ese repo concreto si falla; seguir con el resto.
|
||||
|
||||
### 2. Para cada repo, mostrar estado
|
||||
### 2. Detectar secrets antes de commitear
|
||||
|
||||
Para cada repo dirty, listar archivos modificados/nuevos y comprobar nombres sospechosos:
|
||||
|
||||
```bash
|
||||
for r in $REPOS; do
|
||||
echo "=== $r ==="
|
||||
( cd "$r" && git status -sb && echo "" )
|
||||
( cd "$r" \
|
||||
&& git status --porcelain | awk '{print $2}' \
|
||||
| grep -E '(^|/)(\.env(\..*)?$|.*credentials.*|.*\.key$|.*\.pem$|id_rsa.*|.*secret.*|.*token.*\.txt$)' \
|
||||
| head -5
|
||||
)
|
||||
done
|
||||
```
|
||||
|
||||
### 3. Manejar dirty trees
|
||||
Si la lista de coincidencias **no está vacía**, abortar el push completo, listar los archivos sospechosos y pedir al usuario que los gestione (añadir a `.gitignore`, mover, o decidir explícitamente que entren).
|
||||
|
||||
- Si **algún repo** tiene cambios sin commitear: lista los archivos al usuario y **pregunta** qué hacer:
|
||||
- (a) commitear todo con un mensaje (usar `$ARGUMENTS` si está, si no preguntar)
|
||||
- (b) stashear y seguir solo con los commits ahead
|
||||
- (c) abortar
|
||||
- Nunca commitear sin permiso explícito.
|
||||
### 3. Auto-commitear dirty trees
|
||||
|
||||
Para cada repo con cambios sin commitear:
|
||||
|
||||
```bash
|
||||
for r in $REPOS; do
|
||||
( cd "$r"
|
||||
[ -z "$(git status --porcelain)" ] && exit 0 # limpio, nada que hacer
|
||||
git add -A
|
||||
if [ -n "$ARGUMENTS" ]; then
|
||||
MSG="$ARGUMENTS"
|
||||
else
|
||||
MSG="$(generate_auto_message)" # patrón descrito en sección 'Argumento'
|
||||
fi
|
||||
git commit -m "$MSG" \
|
||||
-m "Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>" 2>&1 | tail -3
|
||||
)
|
||||
done
|
||||
```
|
||||
|
||||
`generate_auto_message` debe inspeccionar `git diff --cached --stat` y producir un subject como `feat(notebook): N cambios` cuando todos los paths comparten prefijo, o `chore: auto-commit` si están dispersos.
|
||||
|
||||
### 4. Push de cada repo
|
||||
|
||||
@@ -80,13 +110,15 @@ for r in $REPOS; do
|
||||
&& if git rev-parse --abbrev-ref --symbolic-full-name @{u} >/dev/null 2>&1; then
|
||||
git push origin "$BRANCH" 2>&1 | tail -3
|
||||
else
|
||||
echo "[$r] no upstream para '$BRANCH' — saltado"
|
||||
git push -u origin "$BRANCH" 2>&1 | tail -3
|
||||
fi
|
||||
)
|
||||
done
|
||||
```
|
||||
|
||||
### 5. fn sync con credenciales de pass
|
||||
Si `push` rechaza por non-fast-forward (rama behind), no abortar el resto. Reportar ese repo concreto y sugerir `/full-git-pull` antes; seguir con los demás repos.
|
||||
|
||||
### 5. fn sync
|
||||
|
||||
```bash
|
||||
USER=$(pass registry/basicauth-user | head -1)
|
||||
@@ -97,14 +129,15 @@ export REGISTRY_API_TOKEN="$TOKEN"
|
||||
./fn sync
|
||||
```
|
||||
|
||||
Si `pass` falla con "decryption failed" → gpg-agent locked. Pedir al usuario que ejecute `pass show registry/api-token` en su terminal real (Bash tool no tiene TTY) y reintentar.
|
||||
Si `pass` falla con "decryption failed" → gpg-agent bloqueado. Pedir al usuario que ejecute `pass show registry/api-token` en su terminal real (Bash tool no tiene TTY) y reintentar.
|
||||
|
||||
### 6. Resumen
|
||||
|
||||
Imprimir tabla concisa: para cada repo, branch, commits pusheados o "ya estaba al día". Y resultado de `fn sync` (sent / received / imported).
|
||||
Tabla concisa: por repo, commits creados (cuántos y subject), commits pusheados, o "ya estaba al día". Y resultado de `fn sync` (sent / received / imported).
|
||||
|
||||
## Notas
|
||||
|
||||
- Es responsabilidad del comando **pushear**, no decidir qué commitear. Solo commitea si el usuario lo aprueba explícitamente.
|
||||
- Los submodules del directorio `cpp/vendor/` (imgui, implot, glfw, tracy, implot3d) se ignoran (son mirrors upstream, no se pushean desde aquí).
|
||||
- Si una rama va `behind` el remote, abortar el push de ese repo y avisar para correr `/full-git-pull` primero.
|
||||
- **Modo no-interactivo por diseño.** El usuario prefiere commits frecuentes y push rápido. No se pregunta si commitear ni se pide mensaje (salvo que se pase via `$ARGUMENTS`).
|
||||
- **Secrets son la única razón para abortar antes de commitear.** Cualquier patrón sospechoso (`.env`, credenciales, claves) detiene el flujo y se reporta al usuario.
|
||||
- Submodules `cpp/vendor/` (mirrors upstream) se ignoran.
|
||||
- Si un sub-repo va `behind` el remote, su push se omite con un mensaje (no se aborta el resto). El usuario corre `/full-git-pull` cuando le convenga.
|
||||
|
||||
Reference in New Issue
Block a user