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>
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
# 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`
|
||||
Reference in New Issue
Block a user