Files
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

10 KiB

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

# 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.shlog::step, log::info, log::ok, log::warn, log::error; internal emit via log::emit
  • utils.shutil::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.ageage --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 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

# 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:

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