Fase 2: 04_sanitize.py - scrubbing de secretos de skills/agentes/plans (10 secretos unicos, gate en verde)

This commit is contained in:
2026-07-29 00:35:59 +00:00
parent 21bc219f31
commit 837f91060f
79 changed files with 10153 additions and 0 deletions
@@ -0,0 +1,124 @@
# Plan: Instalar Claude Code system-wide (username-agnostic, última versión) en el Dockerfile
## Context
El [Dockerfile](Dockerfile) instala Claude Code vía el repo apt oficial (`claude-code`,
líneas 147155) desde el commit `7096b11`. Eso provocó dos problemas:
1. **Versión vieja**: el canal apt `stable` va por detrás del canal `latest`. En este
contenedor hay `2.1.197`, mientras que `latest` ya está en `2.1.207`.
2. **MCPs no cargan**: verificado que es *estructural*, no de versión. El usuario declaró sus
MCPs (gitea, docmost, github-personal, penpot, atlassian) bajo la clave `mcpServers` dentro
de `~/.claude/settings.json`, pero **Claude Code no lee `mcpServers` desde `settings.json`**.
`claude mcp list` lo confirmó: solo aparecen los conectores de claude.ai, ninguno de los del
usuario. Los MCPs de usuario viven en `~/.claude.json` (archivo hermano de `.claude/`, no
dentro), en `.mcp.json` de proyecto, o en `/etc/claude-code/managed-mcp.json` (enterprise).
Intentos previos y por qué fallaron:
- `curl … install.sh | bash` (commit original): deja el binario en `~/.local/bin` del usuario que
instala (root) → inalcanzable para otros HOME_USER.
- `HOME=/usr/local/claude … install.sh` (`be1a141`): el binario resuelve su home por el registro
del SO, ignoró el override y volvió a caer en `/root`.
- apt `claude-code` (`7096b11`): quedó en `/usr/bin` (bien para multi-usuario) pero atado al canal
`stable` desactualizado.
**Objetivo**: que `claude` esté disponible por defecto para **cualquier nombre de usuario** del
SO, siempre en la **última versión**, con **auto-update en runtime** funcionando, y sin depender
de trucos de `$HOME`/`.bashrc`.
## Alcance (confirmado con el usuario)
- **Este repo (Dockerfile)**: SOLO arreglar la instalación de Claude Code.
- **MCPs**: NO se toca la imagen. Se documenta la guía para que el usuario los reubique vía sus
volúmenes (sección "Guía MCPs" abajo).
## Enfoque recomendado
Descargar el binario nativo standalone directamente del canal oficial `latest` (el mismo artefacto
que `install.sh` usa internamente), verificar su checksum, y colocarlo en `/usr/local/bin/claude`
(modo 0755, root). Esa ruta ya está en el PATH por defecto de todo usuario (igual que `gh`,
`kubectl`, `docker`), así que es completamente independiente del nombre de usuario y no necesita
exports en `.bashrc`.
El auto-update en runtime sigue funcionando **por usuario**: el updater nativo descarga nuevas
versiones en el propio `~/.local/share/claude/versions/` de cada usuario, independiente del binario
root de `/usr/local/bin`. La línea existente `export PATH="$HOME/.local/bin:$PATH"` (línea 176)
hace que esa copia actualizada por usuario tome precedencia. El binario base de la imagen se
refresca además en cada build de CI.
## Cambios en [Dockerfile](Dockerfile)
### 1. Reemplazar el bloque apt (líneas 147155) por descarga directa del binario `latest`
`python3` ya está disponible en esta etapa (viene de `python3-pip`), así que se usa para parsear el
`manifest.json` de forma robusta. El base es Debian/glibc → variante `linux-<arch>` (no musl).
```dockerfile
# Installing Claude Code (system-wide, latest native build, accessible by any user)
# Pull the standalone native binary straight from the official 'latest' release
# channel (the same artifact install.sh uses internally) and drop it on the
# system PATH at /usr/local/bin -- already on every user's PATH, like gh/kubectl.
# Avoids install.sh's per-user ~/.local/bin layout (unreachable for other users)
# and the apt 'stable' channel lag that shipped an outdated build. Runtime
# auto-update still works per user: the native updater writes new versions into
# each user's own ~/.local/share/claude/versions.
RUN set -eux; \
case "$(dpkg --print-architecture)" in \
amd64) CC_ARCH=x64 ;; \
arm64) CC_ARCH=arm64 ;; \
*) echo "unsupported architecture: $(dpkg --print-architecture)" >&2; exit 1 ;; \
esac; \
CC_BASE="https://downloads.claude.ai/claude-code-releases"; \
CC_VERSION="$(curl -fsSL "${CC_BASE}/latest")"; \
CC_CHECKSUM="$(curl -fsSL "${CC_BASE}/${CC_VERSION}/manifest.json" \
| python3 -c "import sys,json;print(json.load(sys.stdin)['platforms']['linux-${CC_ARCH}']['checksum'])")"; \
curl -fsSL "${CC_BASE}/${CC_VERSION}/linux-${CC_ARCH}/claude" -o /tmp/claude; \
echo "${CC_CHECKSUM} /tmp/claude" | sha256sum -c -; \
sudo install -m 0755 -o root -g root /tmp/claude /usr/local/bin/claude; \
rm -f /tmp/claude; \
claude --version
```
### 2. Eliminar la línea de auto-update específica de apt (líneas 177178)
```dockerfile
# Let Claude Code auto-upgrade its apt package in the background when a new version ships
RUN echo 'export CLAUDE_CODE_PACKAGE_MANAGER_AUTO_UPDATE=1' | sudo tee -a /usr/bin/.bashrc
```
Ya no aplica (no es instalación apt). El auto-update nativo funciona por defecto sin esa env var.
Se **conserva** la línea 176 (`export PATH="$HOME/.local/bin:$PATH"`) porque es de propósito
general y ayuda a que el claude auto-actualizado por usuario tome precedencia.
### 3. Bump de versión en [README.md](README.md)
`1.4.1``1.4.2` (mismo patrón que los commits previos).
## Guía MCPs (fuera de la imagen — lo aplica el usuario en sus volúmenes)
Causa raíz: `mcpServers` en `~/.claude/settings.json` es ignorado. El resto de `settings.json`
(`permissions`, `hooks`, `model`, `enabledPlugins`, `env`, `theme`, etc.) **sí es válido y se
queda ahí**.
Pasos:
1. Mover el bloque `mcpServers` de `~/.claude/settings.json` al archivo `~/.claude.json`
(en el HOME, hermano del directorio `.claude/`), como clave top-level:
```json
{ "mcpServers": { "gitea": { "type": "http", "url": "…", "headers": { … } }, "docmost": { … } } }
```
2. Persistir `~/.claude.json` en el volumen por usuario, montado **read-write** (Claude reescribe
ese archivo con historial de proyectos; no debe ser read-only). El volumen actual que monta
`~/.claude/` no lo cubre porque `~/.claude.json` está fuera de ese directorio.
3. Borrar el bloque `mcpServers` obsoleto de `settings.json` para evitar confusión.
## Verificación
1. **Build**: `docker build -t vscode-server:test .` (o vía el workflow de Gitea). Confirmar que el
nuevo `RUN` imprime `claude --version` = `2.1.207` (o superior) sin error de checksum.
2. **Multi-arch**: el `case` cubre amd64/arm64; el build de CI es `linux/amd64,linux/arm64`.
3. **Username-agnostic**: correr el contenedor y, como el usuario por defecto y como otro usuario
distinto, verificar `which claude` → `/usr/local/bin/claude` y que `claude --version` responde.
4. **Auto-update runtime**: tras un rato de uso, confirmar que aparece `~/.local/share/claude/versions/`
en el home del usuario (update nativo por usuario) sin permisos root.
5. **MCPs** (tras aplicar la guía en el volumen): `claude mcp list` debe listar gitea/docmost/
github-personal/penpot/atlassian como `Connected`.