# Mac

Cositas de macos y apple

# Montar un punto de montaje NFS en MacOs 12 Monterey

## Introducción
A veces se me olvida que Mac tiene sus cositas. En mi caso tengo una raspberry pi 4B que es mi centro de backups, DCHP, etc. Habitualmente monto alguna unidad vía NFS con mi ordenador personal con linux, y como no quería hacer lo propio con mi Macbook Pro con chip M1 y Monterey (12.5) como versión del SO

> Tras unas horas de trabajo, he comprendido que es mucho mejor instalar un [servidor APF con Netatalk](https://wiki.castris.com/books/mac/page/configurar-un-servidor-apf-con-netatalk-en-una-raspberry-pi) y permitir el uso de su formato natívo de red, que usar NFS que se le atraganta mucho al Darwin.

### Metodología

Para ello lo primero me cree los directorios que queria (uno por cada endpoint NFS) y luego intente montar uno

```bash
> sudo mkdir /private/backup5t
> sudo make mount -t nfs rbp:/backup5t /private/backup5t
Password:
mount_nfs: can't mount with remote locks when server (rbp) is not running rpc.statd: RPC prog. not avail
mount: /private/backup5t failed with 74
```
Bueno, algo me decía que empezábamos un nuevo lío.

### Verificar NFS remoto
```bash
> showmount -e rbp
Exports list on rbp:
/backup5t                           192.168.1.0/24
```

### Verificar los demonios asociados a nfs
```bash
❯ systemctl status rpcbind.service
● rpcbind.service - RPC bind portmap service
   Loaded: loaded (/lib/systemd/system/rpcbind.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2022-08-07 08:26:48 UTC; 42min ago
     Docs: man:rpcbind(8)
 Main PID: 279 (rpcbind)
    Tasks: 1 (limit: 4915)
   Memory: 2.1M
   CGroup: /system.slice/rpcbind.service
           └─279 /sbin/rpcbind -f -w
❯ systemctl status rpc-statd.service
● rpc-statd.service - NFS status monitor for NFSv2/3 locking.
   Loaded: loaded (/lib/systemd/system/rpc-statd.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
```

Aquí lo vemos. Un servicio de locking que está muerto pero es normal,ya que no tengo configurado nfs v3 o v2.

Y por aquí es donde anda el lio. 

### Solución
Decirle a nuestro mác que use la versión 4 o configurar el servidor para que soporte nfs v3 y nfs4, que no estoy dispuesto, por obsoleto.

```bash
❯ sudo echo ‘nfs.client.mount.options = vers=4’ >> /etc/nfs.conf
❯ sudo mount  -t nfs rbp:/backup5t /private/backup5t
```

Et voila…

![Disco NFS montado en MacOS X Monterey](https://multimedia.castris.com/imagenes/wiki/macos/nfs-mount-mac-monterey.png)

### Solventar el lío a lo bruto
La literatura sobre el tema en Google, o DuckDuck es fantástica. Una vez más muchos posts, y pocas soluciones reales, amén de que muchas son **similares** pero no tienen la misma dinámica. Y esta es una de las propuestas, que tiene un gran handicap.

**Su uso es desaconsejado porque en un entorno de múltiples accesos a un mismo fichero acabarán en una corrupción**
**NO USAR NUNCA nolocks** 

```bash
> sudo mount -o nolocks,resvport,locallocks  -t nfs rbp:/backup5t /private/backup5t
```



##### Aviso
Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. 
También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad.
El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com)

Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18).

# Configurar un servidor APF con netatalk en una Raspberry Pi

## Introducción
Tras un rato con la configuración del **NFS v4** para conectarme desde mi Macbook Pro a mi raspberrypi (linux con[Hypriot](https://blog.hypriot.com/getting-started-with-docker-on-your-arm-device/), he visto que al final perderé el tiempo, la velocidad no es muy agraciada, y encima se me olvidó un detalle, necesito una partición en un de mis discos atados a la raspberry que tengo formato **hfsplus o apfs**. A este punto no encontre nada sobre APFS para linux excepto un repositorio de github [Apple File System for Linux](https://github.com/linux-apfs/linux-apfs-rw)
y yo soy friki pero no idiota como para perder mi tiempo, y menos cuando una de las particiones va a ser mi **Time Machine** o backup.


## Metodología
Debemos realizar los siguientes pasos:
Instalar el soporte de **HPFS+**
Instalar soporte **netatalk** para poder comunicarnos con el protocolo de red de Apple.
Particionar el disco con **parted** ya que el disco de **Time Machine** debe estar formateado y montado como una unidad HPFS+
Modificar el fichero de montaje fstab para que sea permanente
Editar la configuración de netatalk

Después ya podremos comprobar el trabajo realizado.

En el ejemplo vamos a usar un disco de 5TB con dos particiones, una para **hpfs+** y **xfs** 

## Soporte HPFS+
### Actualización del sistema de paquetes
```bash
sudo apt-get update
sudo apt-get upgrade
```
### Instalación de paquetes para HPFS+
Sin ellos no podremos dar soporte a nuestro linux para que lea y escriba en un sistema de ficheros HPFS+

```bash
sudo apt-get install hfsplus hfsutils hfsprogs gdisk
```

### Crear una particion HPFS+
Primero necesitamos crear una partición para usar con dicho sistema de ficheros.

En mi caso voy a formatear un disco duro de 5TB en dos particiones. Una para **xfs** y otra para **hpfs+* 

Es un disco que actualmente tenía dos particiones, una reservada que no borre y otra xfs. En el proceso voy a eliminar las dos particiones para luego crear dos particiones conforme a mis deseos, usando **parted**

Más información  [Parted mejor que fdisk](https://wiki.castris.com/books/tips-sobre-la-administracion-de-linux/page/parted-mejor-que-fdisk)

```bash
❯ sudo parted /dev/sdb
GNU Parted 3.2
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print
Model: Seagate Expansion Desk (scsi)
Disk /dev/sdb: 6001GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system  Name                          Flags
 1      17.4kB  134MB   134MB                Microsoft reserved partition  msftres
 2      135MB   6001GB  6001GB  xfs          BACKUP5T

(parted) rm 2
(parted) rm 1
(parted) print
Model: Seagate Expansion Desk (scsi)
Disk /dev/sdb: 6001GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number  Start  End  Size  File system  Name  Flags

(parted) quit
Information: You may need to update /etc/fstab.

❯ sudo parted -s /dev/sdb mkpart backupt3t 0% 50%
❯ sudo parted -s /dev/sdb mkpart timemachine 50% 100%

❯ sudo parted /dev/sdb
GNU Parted 3.2
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print
Model: Seagate Expansion Desk (scsi)
Disk /dev/sdb: 6001GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system  Name         Flags
 2      1049kB  3001GB  3001GB               backup3t
 1      3001GB  6001GB  3001GB               timemachine

(parted) quit

```

Que bien que ahora podemos formatear las dos particiones.

```bash
❯ sudo mkfs.hfsplus /dev/sdb2
Initialized /dev/sdb2 as a 2795 GB HFS Plus volume
❯ sudo mkfs.xfs /dev/sdb1
meta-data=/dev/sdb1              isize=512    agcount=4, agsize=183141312 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=0
data     =                       bsize=4096   blocks=732565248, imaxpct=5
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=357697, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
```

## Crear las particiones de montaje
Creamos las particiones de montaje para ambos sistemas, y ya que van a aser usadas en un entorno personal le damos los permisos adecuados
```bash
❯ sudo mkdir /timemachine
❯ sudo mkdir /backup3t
```
## Probar el montaje manual
Primero probamos manualmente el montaje, y luego pasaremos a el montaje automático en cada reinicio. 
> Aconsejado cuando hacemos cosas con nuevos dispositivos, y sistemas de ficheros, para liberarnos de problemas en el montaje automático.

El comando de abajo, formateara la partición con las siguientes características (disponible la ayuda man de  man mkfs.hfsplus

- **s** Que creará un formato sensitivo al caso (distinguir mayúsculas de minúsculas) 
- **v** nombre del volumen

> Lo de Apple y las mayusculas y minusculas es que no me entra. Un sistema UNIX como es MacOSX basado en Darwin, en el que coexiste con otros UNIX, que por defecto te instala un sistema sin distinción de caso.

> La opción **J** Crearía el volumen con un fichero de diario o journal en este caso de 512M (máximo). Yo lo considero necesario pues en caso de un problema con el disco en un reinicio, corte de electricidad, es una garantía muy fuerte de que se recuperara la información, y en backups basados en rsync como los es el Time Machine, es más que necesario por la cantidad tan gigante de información que se genera en el journal. Lamentablemente a la fecha no conozco soporte para instalar el journal ya que al montaje, el disco se haria indisponible por un problema de permisos sobre el journal.


```bash
❯ sudo mkfs.hfsplus -s -v timemachine /dev/sdb1
Initialized /dev/sdb1 as a 2795 GB HFS Plus volume

❯ sudo fsck.hfsplus /dev/sdb1
** /dev/sdb1
** Checking HFS Plus volume.
** Detected a case-sensitive catalog.
** Checking Extents Overflow file.
** Checking Catalog file.
** Checking Catalog hierarchy.
** Checking volume bitmap.
** Checking volume information.
** The volume timemachine appears to be OK.
```

![Montaje hfsplus manual](https://multimedia.castris.com/imagenes/wiki/macos/mount-hfsplus.png)
### Montaje automatizado de los discos
Una vez montado podemos ver las opciones del montaje que estarán disponibles en el `/etc/mtab`

```
/dev/sdb1 /timemachine hfsplus rw,relatime,umask=22,uid=0,gid=0,nls=utf8 0 0
```

Editamos el fichero `/etc/fstab`
```bash
❯ sudo cat /etc/fstab |grep time
/dev/sdb1 /timemachine hfsplus rw,relatime,umask=22,uid=0,gid=0,nls=utf8 0 1
```
Con ellas ya tenemos una idea de que poner en el `/etc/fstab`

### Obtención del UUID
Suelo montar las particiones con UUID y con más razón cuando son discos externos, ya que un cambio, eliminación de dispositivo, error, en un reinicio puede cambiar las letras del dispositivo.

```bash
> sudo  blkid
```
![Comando blkid](https://multimedia.castris.com/imagenes/wiki/macos/blkid.png)

### Edición del fstab
```bash
UUID=6bc6f79f-c74f-35a1-b226-092396e3fed1 /timemachine hfsplus rw,relatime,umask=22,uid=0,gid=0,nls=utf8 0 1
UUID=c0f66c48-3a78-4c1a-bc7f-6d4ad854f284 /backup3t xfs  rw,noquota,nofail  0  1
```

## Configuración de netatalk
Una buen guía de netatalk es la [Guia de Archlinux | Netatalk](https://wiki.archlinux.org/title/Netatalk) aunque es bueno darse una leída al propio proyecto [Netatalk](https://netatalk.sourceforge.io/)

Abajo mi configuración 

```bash
❯ cat /etc/netatalk/afp.conf
;
; Netatalk 3.x configuration file
;

[Global]
; Global server settings
; mimic model = TimeCapsule6,106
 log level = default:warn
 log file = /var/log/afpd.log
 hosts allow = 192.168.1.0/24
 spotlight = yes

; [Homes]
; basedir regex = /home

[Pirate]
path = /home/pirate
valid users = pirate

[Backup10t]
path = /backup10t
valid users = pirate

[Backup3t]
path = /backup3t
valid users = pirate

[My Time Machine Volume]
path = /timemachine
time machine = yes
```

Reiniciar **netatatalk** con `sudo systemctl restart netatalk` ya tendremos disponibles nuestras particiones en el mac a través de las unidades de red.

> Nota: El reinicio de netatalk tras algún cambio o el inicio por primera vez, tardará dependiendo de la cantidad de contenidos de las unidades compartidas configuradas.

## Montaje de las particiones
Ya está, ya solo tenemos conectarnos al servidor y montar nuestras particiones.

Desde el Finder > Ir > Conectarse a un servidor (⌘)

![Conectarse a un servidor APF](https://multimedia.castris.com/imagenes/wiki/macos/conectarse-a-un-servidor-apf.png)
![Conectarse  un volumen de un servidor APF](https://multimedia.castris.com/imagenes/wiki/macos/conectar-a-un-volumen-apf.png)

> NOTA: La primera vez que se conecta a un servidor APF tardará un buen rato en terminar la conexión. Sé paciente, sobre todo si tus discos o particiones APF tiene un gran volumen de ficheros y enlaces, ya que este sistema de red, tiene una especie de journal, que tiene que completar. No te desesperes, en mi caso la primera vez tardó casi 10 minutos, ya que el disco `backup10t` tiene casi 8TB de backups con rsync de más de 2 años, lo que hace que su número de inodos usados en enlaces duros sea muy elevado.

## Configurar Time Machine
Ahora ya podemos configurar nuestro Time Machine 
**Preferencias > Time Machine** y disfrutar delo aprendido.

![Configurar Time Machine](https://multimedia.castris.com/imagenes/wiki/macos/mi-time-machine.png)

## Disclaimer o descargo de responsabilidad
Esto es un documento tipo “Yo lo hice así y me funciono”. Eso supone que cuando menos tienes conocimientos, gustas de leer la documentación y tratar de entenderla. Que eres un forofo de las copias de seguridad y que por supuesto, eres consciente de que si haces algo mal la puedes liar. No me vengas luego con llantos. Si te pasa algo yo no soy el culpable. ¿Entendido? Que los disfrutes.

##### Aviso
Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. 
También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad.
El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com)

Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18).

# chattr con Apple MacOs X

## chattr en linux
Uno de los elementos que uso en mis sistemas linux, cuando hay ciertas cosas que quiero proteger de escrituras accidentales o provocadas, es `chattr` un poderos comando que marca con una bandera de inmutabilidad el fichero indicado, si lo usamos con la opción `+i`

```
# chattr +i file_inmutable.txt
```

Con ese comando ni el propio root podrá editar o borrar el fichero hasta que

```
# chattr -i file_inmutable.txt
```


> A file with the 'i' attribute cannot be modified: it cannot be deleted or renamed, no link can be created to this file and no data can be written to the file. Only the superuser or a process possessing the CAP_LINUX_IMMUTABLE capability can set or clear this attribute.


Sin embargo en mi oficina como ordenador de escritorio uso Mac OsX, y es un poco de diferente. Te presento el comando `chflags`

## chflags

Si acudimos al **man* del comando 

```
schg, schange, simmutable
                       set the system immutable flag (super-user only)
uchg, uchange, uimmutable
                       set the user immutable flag (owner or super-user only)
                       
Putting the letters “no” before or removing the letters “no” from a keyword causes the flag to be cleared.  For example:

           nouchg  clear the user immutable flag (owner or super-user only)                       
                       
```

Así que sencillo si queremos proteger contra una posible escritura o borrado un fichero en nuestro mac.

```
> chflags uchg config.xml
```

##### Aviso
Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. 
También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad.
El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com)

Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional).

# Extraer páginas de un PDF en MacOs X desde el shell

## Antecedentes

Que si esta, que si la otra,... un baile de aplicaciones algunas de ellas muy engañosas con el concepto **gratis** cuando en realidad son aplicaciones capadas que buscan tu dinero.

**Opensource** que no es lo mismo y es mejor. En mi artículo [Extraer páginas de un PDF en Linux desde el shell](https://wiki.castris.com/books/linux/page/extraer-paginas-de-un-pdf-en-linux-desde-el-shell) escribí sobre algo parecido para Linux. Hoy le toca el turno a Mac Os.


Tras un incidente con la falta de usabilidad de [Dominio.es](https://www.dominios.es/es) en el que te piden un DNI en el proceso de validación de un cambio de titular, tuve que extraer del PDF que me envió el cliente, las dos imágenes del DNI, y después, juntarlas en una sola imagen (no admiten más de una), para terminar con un, **se me olvide decirte que la imagen no puede tener más de 600px de ancho) realice el trabajo en el shell

## Programa Poppler

[Poppler](https://poppler.freedesktop.org/) es un programa de rendering de PDF basado en [xpdf](https://www.xpdfreader.com/)

Usaremos [Homebrew](https://brew.sh/) para instalarlo. 

```
brew install poppler
```

Con Poppler, extremos las imágenes a través de su binario **pdfimages**

```
pdfimages archivo.pdf prefijo_salida
```

- `archivo.pdf` es el nombre de tu archivo
- `prefijo_salida` es el prefijo que tendrán tus imágenes extraidas

Si lo hacemos así las imágenes saldrán en formato [.ppm](https://es.wikipedia.org/wiki/Formatos_Netpbm) así que tendríamos que convertirlos a JPG pro imperativo de dominios.es.

## Programa ImageMagick

Usaremos uno de los programas de ImageMagick, así que si no lo tenemos (es un super programa, tanto en Linux como en Mac) lo instalaremos.

```
brew install imagemagick
```

Una vez instalado de todos los binarios o programas que instala usaremos varios.

`convert` para convertirlo a otro formato

```
convert prefijo_salida-0000.ppm prefijo_salida-0000.jpg
```

Como tenemos mas de una imagen que bueno un comando

```
for img in *.ppm; do convert "$img" "${img%.ppm}.jpg"; done
```
### Tip 

Si antes de hacer nada leemos el man de **poppler** directamente podemos hacer la extracción a jpg.

Usamos el parametro `-j`

```
pdfimages -j archivo.pdf prefijo_salida
```

## Crear un único archivo

Bueno, cuando vas a subir el fichero descubres que sólo quieren un fichero.

Nos toca usar convert otra vez para añadirlos.

```
convert prefijo_salida-0000.jpg prefijo_salida-0001.jpg +append resultado_final.jpg
```

Ay... que ahora no lo quieren de max de 600px de ancho.

```
convert prefijo_salida-0000.jpg prefijo_salida-0001.jpg -append resultado_final.jpg
```

Observa que `+append` se convirtió en `-append` para crearlo en vertical uno tras otro.

Pero, no. No comprobé que el ancho de cada imagen fuera de menos de 600px, y resulto que tenía 610.

Bueno, ya es el último.

```
convert resultado_final.jpg -resize 600x resultado_final_redimensionado.jpg
```

## Finales

Espero que lo hallas disfrutado. Ahora te dejo que tengo que seguir con mi proyecto, [Baytuka](https://baytuka.com/)


##### Aviso
Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. 
También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad.
El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com)

Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional).

# Secuencia de Apple Script para cambiar colores en Numbers

## Introducción

Puede que muchos no hallais conocido la época del Apple Script para todo, antes de que Steve Jobs, volviera a su casa y la llevara a donde ha llegado. En aquel entonces el Apple Script erá lo mejor para lo makeros frikis. Pro que te permitia cosas impensables en el mundo Windows o en el de linux con las X.

### Applescript para funciones de teclado

Para ir más rápido uso un herramienta imprescindible como makero friki: [BetterTouchTool](https://folivora.ai/) pero puedes apañartelas a pelo. Eso ya es otro cantar que no voya  explicar aqui.

### Secuencia

En este caso uso 3 secuencias para marcar filas o celdas en numbers, cuando ando con la contabilidad. Numbers es maravilloso, pero algunas cosas no son precisamente usables como esta y prefiero tener un secuencia de teclado para ir mas rápido.

Podeis modificar los colores pero recodsar usar el formato de color de mac

![BetterTouchTool](https://multimedia.castris.com/imagenes/wiki/macos/apple-script-numbers.jpg)

#### Color verde

```
tell application "Numbers"
    tell front document
        tell active sheet
            try
                set active_table to (first table whose class of selection range is range)
            on error
                display alert "No selection" buttons {"OK"} default button 1
                return
            end try
            tell active_table
                set background color of selection range to {0, 65535, 0}
            end tell
        end tell
    end tell
end tell
```

#### Color amarillo

```
tell application "Numbers"
    tell front document
        tell active sheet
            try
                set active_table to (first table whose class of selection range is range)
            on error
                display alert "No selection" buttons {"OK"} default button 1
                return
            end try
            tell active_table
                set background color of selection range to {65535, 65535, 0}
            end tell
        end tell
    end tell
end tell
```

#### Color rojo

```
tell application "Numbers"
    tell front document
        tell active sheet
            try
                set active_table to (first table whose class of selection range is range)
            on error
                display alert "No selection" buttons {"OK"} default button 1
                return
            end try
            tell active_table
                set background color of selection range to {65535, 17733, 14906}
            end tell
        end tell
    end tell
end tell

```

##### Aviso
Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. 
También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad.
El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com)

Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional).

# Tips rápidos

Trucos puntuales de macOS y sus apps: una página por tip, con título descriptivo (app + qué quieres hacer + cómo) para que la búsqueda de BookStack encuentre el problema exacto directamente.

# pip3 en macOS (Homebrew): evitar el error externally-managed-environment instalando con pipx

## Instalar programas/script pyhton con pip3 en entorno Mac con Homebrew

Muchas veces en mac quieres instalar algo con `pip` pero tu instalación de `pip3` ewsta mantenida por [Homebrew](https://brew.sh/) y obtines el error de abajo

```
pip3 install "headroom-ai[all]"
error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try brew install
    xyz, where xyz is the package you are trying to
    install.

    If you wish to install a Python library that isn't in Homebrew,
    use a virtual environment:

    python3 -m venv path/to/venv
    source path/to/venv/bin/activate
    python3 -m pip install xyz

    If you wish to install a Python application that isn't in Homebrew,
    it may be easiest to use 'pipx install xyz', which will manage a
    virtual environment for you. You can install pipx with

    brew install pipx

    You may restore the old behavior of pip by passing
    the '--break-system-packages' flag to pip, or by adding
    'break-system-packages = true' to your pip.conf file. The latter
    will permanently disable this error.

    If you disable this error, we STRONGLY recommend that you additionally
    pass the '--user' flag to pip, or set 'user = true' in your pip.conf
    file. Failure to do this can result in a broken Homebrew installation.

    Read more about this behavior here: <https://peps.python.org/pep-0668/>

note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
```

### Resumen

```
This environment is externally managed
╰─> To install Python packages system-wide, try brew install
    xyz, where xyz is the package you are trying to
    install.
```
    
### Solución

Usar `pipx`

```
brew install pipx
pipx install "headroom-ai[all]"
  installed package headroom-ai 0.26.0, installed using Python 3.14.6
  These apps are now available
    - headroom
done! ✨ 🌟 ✨
```



##### Aviso
Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. 
También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad.
El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com)

Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional).

# Localizar y reabrir sesiones de gentle-shell/pi (y la trampa de la hora UTC en el nombre del fichero)

## Antecedentes

Tras un reinicio del Mac con herdr gestionando mis paneles, me encontré con dos despistes seguidos: los paneles que habían nacido con `gentle-shell` volvieron como `pi` a secas, y cuando quise localizar la sesión de un mensaje concreto no sabía ni de qué hora era ni dónde vivía el fichero. Esta nota es el chuleta que me habría ahorrado el rato perdido.

## Dónde viven las sesiones

- **gentle-shell:** `~/.gentle-shell/agent/sessions/<proyecto>/<fecha>_<id>.jsonl` — un fichero por sesión, agrupados por directorio de trabajo. Ejemplo: `--Users-abkrim-mi-proyecto--`

- **pi clásico:** `~/.pi/agent/sessions/`, con la misma filosofía

Para encontrar la sesión de hoy, lo rápido es ordenar por fecha:

```bash
ls -lt ~/.gentle-shell/agent/sessions/*/ | head
```

## La trampa: la hora del fichero es UTC

El nombre de cada fichero lleva la fecha en formato ISO, pero **en UTC**, no en tu hora local. Un fichero `2026-10-29T05-47-16-683Z` se creó a las **06:47** de España (CET, `+1`). Si buscas «la sesión de las seis y cuarenta y siete» y no la ves, es porque la hora del nombre va una hora (dos en verano) por detrás de tu reloj.

Para no liarte, compara siempre contra el reloj UTC:

```bash
date '+%H:%M %Z'; date -u '+UTC: %H:%M'
```

## Cómo reabrir una sesión

- **Desde el shell**, con `gentle-shell`, que le pasa los argumentos que no conoce al pi de debajo:

```bash
gentle-shell --session ~/.gentle-shell/agent/sessions/<proyecto>/<fichero>.jsonl
```

- **Dentro de un pi vivo:** el comando `/resume` abre el selector de sesiones.

Un matiz importante: reabrir una sesión de esa forma **no es lo mismo que recuperar el hilo de trabajo**. El contexto entre sesiones me lo trae la memoria persistente (Engram), no el fichero de sesión: dos sesiones distintas pueden continuar el mismo trabajo aunque el `.jsonl` de la primera siga cerrado.

## Relacionado — el mismo incidente

- **Tras un reinicio, herdr puede relanzar los paneles de `gentle-shell` como `pi` a secas** (`pi --session <fichero>`), sin las herramientas propias de gentle (subagentes, revisión…), y lo hace en silencio: la conversación continúa en el mismo fichero de sesión y el agente sigue trabajando, así que no hay error que lo delate. Para saber en qué modo corre un panel: `ps -o command= -p $PPID` — `node .../gentle-shell` es modo gentle, `-zsh` es pi pelado. La recuperación es cerrar ese pi y relanzar la sesión con `gentle-shell --session <fichero>`.

- **`herdr update` no se puede lanzar desde dentro de un panel de herdr:** el propio comando lo rechaza. Toca abrir una ventana de terminal fuera de herdr y ejecutarlo ahí.