Files
STP/CLAUDE.md
T
msaldain bd78fd9fbe Configuracion inicial completa del entorno personal
Modulos de restauracion:
- bootstrap: instala yq, age y dependencias base (curl, wget, git, nano, gpg)
- ssh: descifra e instala claves SSH desde secrets/sshKeys.tar.gz.age
- registry: aplica paquetes apt/snap/flatpak, dotfiles, servicios y configs Docker
- thunderbird: instala Thunderbird snap y restaura perfil desde ZIP
- claudeCode: configura repositorio apt de Anthropic e instala claude-code
- easyEffects: restaura configuracion y presets desde ZIP
- wireplumber: restaura dispositivo Bluetooth por defecto y perfiles de audio
- cups: restaura impresoras y drivers PPD desde ZIP

Scripts de captura (correr antes de push):
- scripts/encryptSsh.sh: cifra ~/.ssh con age
- scripts/thunderbird/capture.sh: captura perfil de Thunderbird snap
- scripts/easyEffects/capture.sh: captura config de EasyEffects flatpak
- scripts/wireplumber/capture.sh: captura estado de WirePlumber
- scripts/cups/capture.sh: captura impresoras CUPS y PPDs (requiere sudo)

Registro de aplicaciones (config/registry.yaml):
- 9 paquetes apt, 1 snap (dbeaver-ce), 22 flatpaks incluyendo VSCodium,
  Bitwarden, Inkscape, LibreOffice, OBS Studio, Nextcloud Desktop, entre otros

Secretos incluidos:
- secrets/sshKeys.tar.gz.age: claves SSH cifradas con age
- secrets/thunderbirdProfile.zip: perfil de Thunderbird sin emails ni cache
- secrets/easyEffectsConfig.zip: ajustes y presets de salida de audio
- secrets/wireplumberState.zip: estado de audio incluyendo auriculares Bluetooth
- secrets/cupsConfig.zip: 5 impresoras configuradas con sus drivers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 18:16:40 -03:00

188 lines
10 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What this project is
STP (Sistema de Transferencia Personal) is a personal machine-setup automation tool. Running it on a fresh Ubuntu LTS install configures the machine to match the owner's environment: packages, PPAs, SSH keys, dotfiles, audio (PipeWire), video drivers, systemd services, and application configurations. Files (documents, media) are handled separately by Nextcloud and are out of scope.
## Key commands
```bash
# First-time setup on a new machine
bash <(curl -fsSL https://gitea.mateosaldain.uy/mateo/stp/raw/branch/main/bootstrap.sh)
# Run all modules
bash stp.sh
# Run a single module
bash stp.sh --module registry
# Skip specific modules
bash stp.sh --skip ssh
# List modules in execution order
bash stp.sh --list
```
## Architecture
**Execution flow:** `bootstrap.sh` → clone repo from Gitea → `stp.sh` → modules in the order defined by `config/modules`
**`stp.sh`** reads module order from `config/modules` (plain text, one name per line, `#` comments — no `yq` required at this level), then runs each `modules/<name>.sh` as a subprocess inheriting the exported `stpRoot` variable.
**Modules** (`modules/<name>.sh`) source `lib/log.sh`, `lib/utils.sh`, and optionally `lib/yaml.sh`. All modules are idempotent — they check current state before acting.
Current modules in execution order:
- `bootstrap` — installs `yq` and `age` (required by all other modules)
- `ssh` — decrypts `secrets/sshKeys.tar.gz.age` with `age` and installs keys into `~/.ssh`
- `registry` — reads `config/registry.yaml` and applies every entry (packages, dotfiles, services, drivers, audio)
- `thunderbird` — installs Thunderbird (snap) and restores profile from `secrets/thunderbirdProfile.zip`
- `claudeCode` — configures the Anthropic apt repository and installs `claude-code`
- `easyEffects` — restores EasyEffects config and presets from `secrets/easyEffectsConfig.zip`
- `wireplumber` — restores WirePlumber state (default audio device, Bluetooth profiles) from `secrets/wireplumberState.zip`
- `cups` — restores CUPS printer definitions and PPD drivers from `secrets/cupsConfig.zip`
**`modules/registry.sh`** — the main workhorse. Reads all entries from `config/registry.yaml` and dispatches each one to a handler based on its `type`. Supported types: `ppa`, `apt`, `snap`, `flatpak`, `dotfile`, `service`, `pipewire`, `video`, `docker`.
**`config/registry.yaml`** — the single list of everything to configure on the machine. Adding a new entry is all that's needed to have STP apply it on the next run. Entries are idempotent — each handler checks current system state before acting.
**`config/settings.yaml`** — machine-independent settings: Gitea host/user/repo coordinates, user identity (`name`, `email`, `username`), and dotfiles `backup` flag.
**`lib/`** — shared helpers sourced by modules:
- `log.sh``log::step`, `log::info`, `log::ok`, `log::warn`, `log::error`; internal emit via `log::emit`
- `utils.sh``util::cmdExists`, `util::isAptInstalled`, `util::isSnapInstalled`, `util::isFlatpakInstalled`, `util::isYamlNull`, `util::confirm`, `util::requireSudo`, `util::keepSudoAlive`, `util::aptUpdateOnce`
- `yaml.sh` — thin wrapper around `yq` v4: `yaml::get`, `yaml::getArray`, `yaml::has`
**`dotfiles/`** — mirrors `$HOME/` structure. Files referenced by `type: dotfile` entries in the registry become symlinks in the real home directory. If a real file already exists at the destination, it is renamed to `${destination}.stpbackup` before the symlink is created.
**`docker/`** — stores Docker configurations (Compose files, Dockerfiles, etc.) organized by service: `docker/<id>/`. Files are symlinked to the configured `destination` (default `~/docker/<id>`). If `autostart: true`, `docker compose up -d` is run after deploying.
**`secrets/`** — encrypted and configuration backups, all safe to commit:
- `sshKeys.tar.gz.age``age --passphrase`-encrypted tar of `~/.ssh`
- `thunderbirdProfile.zip` — Thunderbird profile (accounts, filters, extensions; excludes emails and cache)
- `easyEffectsConfig.zip` — EasyEffects settings and output presets
- `wireplumberState.zip` — WirePlumber state (default audio sink, Bluetooth device profiles, per-app volumes)
- `cupsConfig.zip` — CUPS `printers.conf` and PPD driver files for all configured printers
**`scripts/`** — capture scripts to run on the current machine before pushing:
- `encryptSsh.sh` — encrypts `~/.ssh` into `secrets/sshKeys.tar.gz.age`
- `thunderbird/capture.sh` — captures Thunderbird Snap profile into `secrets/thunderbirdProfile.zip`
- `easyEffects/capture.sh` — captures EasyEffects Flatpak config into `secrets/easyEffectsConfig.zip`
- `wireplumber/capture.sh` — captures WirePlumber state into `secrets/wireplumberState.zip`
- `cups/capture.sh` — captures CUPS printer config into `secrets/cupsConfig.zip` (requires sudo)
**`config/keys/`** — GPG public keys for third-party apt repositories:
- `claude-code.asc` — Anthropic signing key for the Claude Code apt repository
**`.claude/`** — Claude Code project configuration:
- `settings.json` — allowed bash commands for this project
- `style.md` — style guide (camelCase, Clean Code, no dry-run)
- `commands/new-module.md``/new-module <name>` — scaffolds a new module
- `commands/addEntry.md``/addEntry <description>` — adds an entry to the registry
- `commands/encrypt-ssh.md``/encrypt-ssh` — guides SSH key encryption
## Currently saved configurations
### Packages (via registry)
| ID | Type | Package |
|---|---|---|
| curl, wget, git, vim, htop, tree, unzip | apt | same as ID |
| buildEssential | apt | build-essential |
| virtualbox | apt | virtualbox |
| dbeaverCe | snap | dbeaver-ce |
| vscodium | flatpak | com.vscodium.codium |
| filezilla | flatpak | org.filezillaproject.Filezilla |
| angryIpScanner | flatpak | org.angryip.ipscan |
| anydesk | flatpak | com.anydesk.Anydesk |
| bitwarden | flatpak | com.bitwarden.desktop |
| bottles | flatpak | com.usebottles.bottles |
| bruno | flatpak | com.usebruno.Bruno |
| nextcloudDesktop | flatpak | com.nextcloud.desktopclient.nextcloud |
| easyEffects | flatpak | com.github.wwmm.easyeffects |
| flatseal | flatpak | com.github.tchx84.Flatseal |
| warehouse | flatpak | io.github.flattool.Warehouse |
| freecad | flatpak | org.freecad.FreeCAD |
| hidamari | flatpak | io.github.jeffshee.Hidamari |
| inkscape | flatpak | org.inkscape.Inkscape |
| libreoffice | flatpak | org.libreoffice.LibreOffice |
| logseq | flatpak | com.logseq.Logseq |
| obsStudio | flatpak | com.obsproject.Studio |
| openshot | flatpak | org.openshot.OpenShot |
### Application configurations (via modules)
| Module | Secret | What is restored |
|---|---|---|
| `ssh` | `secrets/sshKeys.tar.gz.age` | SSH keys with correct permissions |
| `thunderbird` | `secrets/thunderbirdProfile.zip` | Accounts, filters, extensions (Snap; excludes emails) |
| `claudeCode` | `config/keys/claude-code.asc` | Anthropic apt repo + claude-code package |
| `easyEffects` | `secrets/easyEffectsConfig.zip` | Settings DB and output presets (HB-Flat, HB-Lite, HB-Mid, Heavy Bass) |
| `wireplumber` | `secrets/wireplumberState.zip` | Default audio sink (Bluetooth headphones), A2DP profile, per-app volumes |
| `cups` | `secrets/cupsConfig.zip` | 5 printers: Epson L8050 WiFi, Canon MP230, Samsung M2020, POS80, Cups PDF |
## Adding a new package
Add an entry to `config/registry.yaml`. The registry handles: `ppa`, `apt`, `snap`, `flatpak`, `dotfile`, `service`, `pipewire`, `video`, `docker`.
Use `/addEntry <description>` for guided entry creation.
For complex setups that require steps beyond what the registry types support (GPG key import, profile restoration, custom installers), create a dedicated module with `/new-module <name>`.
## Adding a new application configuration backup
1. Create `scripts/<appName>/capture.sh` — reads from the app's data directory and writes a ZIP to `secrets/`
2. Create `modules/<appName>.sh` — checks if app is installed, checks if config already exists, restores from ZIP
3. Add `<appName>` to `config/modules` after `registry`
4. Run `bash scripts/<appName>/capture.sh` on the current machine
5. Commit the generated file in `secrets/`
Restoration is automatic on the next `stp.sh` run. All modules are idempotent — if the config already exists on the target machine, the restore is skipped.
## Updating a saved configuration
Re-run the corresponding capture script and commit the updated file:
```bash
bash scripts/thunderbird/capture.sh && git add secrets/thunderbirdProfile.zip
bash scripts/easyEffects/capture.sh && git add secrets/easyEffectsConfig.zip
bash scripts/wireplumber/capture.sh && git add secrets/wireplumberState.zip
bash scripts/cups/capture.sh && git add secrets/cupsConfig.zip
bash scripts/encryptSsh.sh && git add secrets/sshKeys.tar.gz.age
```
## Restoring on a new machine
```bash
# 1. Bootstrap (clones repo and runs all modules)
bash <(curl -fsSL https://gitea.mateosaldain.uy/mateo/stp/raw/branch/main/bootstrap.sh)
```
The bootstrap runs all modules automatically. Each module skips gracefully if its secret is missing or if the configuration is already in place.
**After WirePlumber restore**, restart the session manager to apply the Bluetooth device as default:
```bash
systemctl --user restart wireplumber
```
## Environment variables
| Variable | Default | Effect |
|---|---|---|
| `stpDir` | `~/.stp` | Clone destination used by `bootstrap.sh` |
| `stpLogFile` | `/tmp/stp-<timestamp>.log` | Path for the full execution log |
## Style guide (enforced on all scripts)
See `.claude/style.md` for the full guide. Key rules:
- **camelCase everywhere**: variables, functions, file names — no underscores, no hyphens in identifiers
- **No abbreviations**: `packageName` not `pkg`, `serviceName` not `svc`, `sourceFile` not `src`; `temporaryDirectory` not `tempDir`, `sourceDirectory` not `sourceDir`
- **Small functions with one responsibility**: extract any named block into a function
- **Boolean functions named as questions**: `printersAreConfigured()`, `wireplumberStateExists()`
- **No `--dry-run`**: the system is idempotent — it checks state before acting
- **No `util::run` wrapper**: call commands directly
- **Comments only for WHY**, never for WHAT
- **Pre-increment `((++n))`** not post-increment `((n++))` — post-increment of 0 exits with code 1 under `set -e`