diff --git a/.claude/commands/full-git-pull.md b/.claude/commands/full-git-pull.md index e61b5b19..c4404e89 100644 --- a/.claude/commands/full-git-pull.md +++ b/.claude/commands/full-git-pull.md @@ -70,7 +70,36 @@ git submodule update --init --recursive 2>&1 | tail -10 CGO_ENABLED=1 ./fn index 2>&1 | tail -3 ``` -### 5. fn sync +### 5. Pull del repo de pass (`~/.password-store`) + +El password store es su propio repo Git en Gitea (`dataforge/pass-secrets`). `pass insert/edit/rm` commitea automaticamente, asi que aqui SOLO hay que pullear los commits remotos. + +```bash +PASS_DIR="$HOME/.password-store" +if [ -d "$PASS_DIR/.git" ]; then + ( cd "$PASS_DIR" \ + && DIRTY=$(git status --porcelain | wc -l) \ + && if [ "$DIRTY" -gt 0 ]; then + git stash push -m "auto-stash before /full-git-pull" --include-untracked >/dev/null + STASHED=1 + else + STASHED=0 + fi \ + && git fetch origin 2>&1 | tail -1 \ + && git pull --ff-only 2>&1 | tail -3 \ + && if [ "$STASHED" = "1" ]; then + git stash pop 2>&1 | tail -3 + fi + ) +fi +``` + +Reglas: +- Mismo patron que el resto de repos: stash → fetch → pull --ff-only → pop. +- Si `--ff-only` falla por divergencia, reportar y seguir; no resolver a mano. +- Si `stash pop` da conflicto, avisar al final. + +### 6. fn sync ```bash USER=$(pass registry/basicauth-user | head -1) @@ -81,11 +110,11 @@ export REGISTRY_API_TOKEN="$TOKEN" ./fn sync ``` -Si `pass` falla → gpg-agent bloqueado, pedir al usuario `pass show registry/api-token` en su terminal real. +Si `pass` falla → gpg-agent bloqueado, pedir al usuario `pass show unlock` en su terminal real (entrada dummy que devuelve "Desbloqueada!" sin exponer API keys). -### 6. Resumen +### 7. Resumen -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. +Tabla concisa: por repo, commits pulleados o "ya estaba al día"; estado de `pass-secrets`; 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 diff --git a/.claude/commands/full-git-push.md b/.claude/commands/full-git-push.md index 78a6466f..8c58c19f 100644 --- a/.claude/commands/full-git-push.md +++ b/.claude/commands/full-git-push.md @@ -135,7 +135,37 @@ Reglas: 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 +### 5. Push del repo de pass (`~/.password-store`) + +El password store es su propio repo Git en Gitea (`dataforge/pass-secrets`). `pass insert/edit/rm` ya commitea automaticamente, por lo que aqui SOLO hay que pushear los commits locales. + +```bash +PASS_DIR="$HOME/.password-store" +if [ -d "$PASS_DIR/.git" ]; then + ( cd "$PASS_DIR" \ + && DIRTY=$(git status --porcelain | wc -l) \ + && if [ "$DIRTY" -gt 0 ]; then + echo "[warn] $PASS_DIR tiene cambios sin commitear; pass deberia commitear solo. Saltando push." + else + BRANCH=$(git rev-parse --abbrev-ref HEAD) \ + && AHEAD=$(git rev-list --count @{u}..HEAD 2>/dev/null) \ + && if [ "${AHEAD:-0}" -gt 0 ]; then + echo "[push] pass-secrets ($BRANCH, $AHEAD commits ahead)" + git push origin "$BRANCH" 2>&1 | tail -3 + else + echo "[skip] pass-secrets (up-to-date)" + fi + fi + ) +fi +``` + +Reglas: +- NO hacer `git add` ni `git commit` en `~/.password-store` (pass lo gestiona). Si hay dirty tree, avisar y saltar. +- NO escanear `*.gpg` por patrones de secrets — son secrets cifrados, su contenido es opaco. +- El push usa el remote ya configurado (`dataforge/pass-secrets` en Gitea). + +### 6. fn sync ```bash USER=$(pass registry/basicauth-user | head -1) @@ -146,11 +176,11 @@ export REGISTRY_API_TOKEN="$TOKEN" ./fn sync ``` -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. +Si `pass` falla con "decryption failed" → gpg-agent bloqueado. Pedir al usuario que ejecute `pass show unlock` en su terminal real (Bash tool no tiene TTY) y reintentar. Esa entrada es un dummy que solo muestra `Desbloqueada!` para cachear el passphrase sin exponer ninguna API key. -### 6. Resumen +### 7. Resumen -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). +Tabla concisa: por repo, commits creados (cuántos y subject), commits pusheados, o "ya estaba al día". Estado de `pass-secrets` (pushed / skipped / dirty). Y resultado de `fn sync` (sent / received / imported). ## Notas diff --git a/.claude/rules/frontend_theming.md b/.claude/rules/frontend_theming.md index 9dbb2fb3..ddea0df6 100644 --- a/.claude/rules/frontend_theming.md +++ b/.claude/rules/frontend_theming.md @@ -9,3 +9,19 @@ El sistema de UI es Mantine v9. Todos los componentes de @fn_library wrappean co **Iconos:** Se usa `@tabler/icons-react` (el set nativo de Mantine), no lucide-react. **Layout:** Se usan los componentes de layout de Mantine: `Group`, `Stack`, `Grid`, `Flex`, `SimpleGrid`, `AppShell`, `Container`, `Box`, `Paper`. + +**AppShell.Navbar / AppShell.Aside (gotchas v9):** + +- NO override `position` via `style` (ej. `style={{ position: "relative" }}`). Mantine aplica `position: fixed` con CSS class; si lo pisas, el slot cae al flow normal y empuja el resto del layout abajo (root altura 2x). +- Para anclar children `position: absolute` (drag handle, badge flotante), el `position: fixed` del propio slot ya actua como containing block — no necesitas relative. +- Por defecto el navbar **empuja** el main (anade `padding-inline-start: navbar-width`). Para **overlay** (navbar tapa main): + ```tsx + + ``` + Idem `paddingInlineEnd: 0` para aside overlay. +- Si quieres backdrop dimming + click-outside-close: usa `` en lugar de `AppShell.Navbar`. +- **Memoizar configs**: `header`/`navbar`/`aside`/`styles` aceptan objetos. Si el componente padre se re-renderiza cada N (tick, ws, etc.), los objetos literales se recrean y Mantine regenera el `