ai-tabs: le tab di iTerm2 e le sessioni degli agenti AI sopravvivono al riavvio
Ho pubblicato ai-tabs, un tool da riga di comando che salva le tab di iTerm2 insieme alle sessioni degli agenti AI che ci girano dentro, e dopo un riavvio (o un crash) le riapre e riprende ogni sessione.
uv tool install ai-tabs
ai-tabs install
Il problema
Lavoro con molti agenti di coding AI in parallelo, e non sempre lo stesso: omp, Claude Code, opencode e hermes. Una tab per progetto, ognuna con la sua sessione, i suoi split, i suoi colori.
Con quattro strumenti diversi, dopo qualche giorno non mi ricordo più quale agente stavo usando per una certa lavorazione, né in quale cartella. Era omp o Claude Code? Il repository principale o un worktree? E ogni agente salva le sue sessioni in un posto diverso, con un comando di resume diverso.
Poi basta un riavvio forzato del Mac e sparisce tutto. iTerm2 può ripristinare le finestre, ma non sa nulla delle sessioni degli agenti: restituisce dieci shell vuote nella home, e tocca ricostruire a memoria quale sessione girava dove, con quale strumento, con quali flag.
Mi è successo, e ricostruire tutto a mano è esattamente il tipo di spreco di tempo e di attenzione che cerco di eliminare.
Perché non ho cambiato terminale
Prima di scrivere codice ho guardato cosa esiste già. Ci sono strumenti ottimi, alcuni pensati proprio per gli agenti AI. Ma con iTerm2 mi trovo bene: split, profili, colori delle tab, shell integration, la sua Python API. Il mio problema era uno solo, il riavvio, e non volevo cambiare radicalmente il modo di lavorare per risolverlo.
| Strumento | Cosa chiede di cambiare | Dopo un riavvio del Mac | Sessioni degli agenti |
|---|---|---|---|
| iTerm2, session restoration | niente | sopravvive a crash e aggiornamenti di iTerm2. Dopo un riavvio torna il contenuto delle finestre, non i processi | no |
| tmux + tmux-resurrect / continuum | lavorare dentro tmux | sessioni, pannelli e cartelle. Riavvia solo una lista prudente di programmi, estendibile a mano | rilancia il comando, non sa quale sessione riprendere |
| Zellij | passare a Zellij | layout e comandi, dietro un “Press ENTER to run” | rilancia il comando così com’era: la sessione torna solo se l’ID era sulla riga di comando |
| herdr | passare all’app o alla TUI di herdr | gli agenti vivono in un server locale, quindi sopravvivono alla chiusura dell’app. Dopo un riavvio i pannelli tornano con una shell nella stessa cartella | non riavvia l’agente e non riprende il lavoro (lo dice la sua FAQ) |
| Claude Squad | gestire gli agenti dalla sua TUI, in tmux e git worktree | dipende da tmux | è un orchestratore di nuove sessioni, non ripristina le tab che avevi |
| cc-session-restore | niente | riapre le sessioni in una sola finestra di iTerm2 | solo Claude Code, con l’ID esatto |
| ai-tabs | niente | finestre, tab, split, colori, profili e cartelle | omp, Claude Code, opencode e hermes, con l’ID esatto |
herdr è quello che mi ha colpito di più: lo stato degli agenti (al lavoro, bloccato, finito) nella sidebar, le macchine remote via SSH, gli agenti che lanciano altri agenti. Sono cose che ai-tabs non fa e non vuole fare. Ma richiede di spostare tutto il lavoro dentro herdr, e dopo un riavvio vero gli agenti vanno comunque fatti ripartire a mano.
cc-session-restore è il più vicino all’idea di ai-tabs, ma copre un solo agente e non
ricostruisce la disposizione delle finestre. ai-tabs prende la strada opposta agli
orchestratori: resta in iTerm2, osserva quello che fai già e lo rimette a posto.
La tabella riflette quello che ho verificato nella documentazione dei progetti a novembre 2026. Sono strumenti che evolvono in fretta.
Come funziona
- Un agente launchd scatta uno snapshot ogni 5 minuti attraverso la Python API di
iTerm2. Un secondo agente,
ai-tabs watch, ascolta gli eventi di layout e scatta uno snapshot circa 2 secondi dopo che una tab, una finestra o un pannello si apre o si chiude. Spostare o ridimensionare una finestra non crea snapshot inutili. - Ogni snapshot contiene finestre, ordine delle tab, titoli, colori, split, dimensioni dei pannelli, profili iTerm2 e, per ogni pannello, la sessione dell’agente: ID, cartella e flag di avvio.
- Gli snapshot vanno in un database SQLite in
~/.local/share/ai-tabs, per 30 giorni. - ai-tabs fissa da solo l’ultimo snapshot prima di un riavvio (
before boot) o prima che molte tab si chiudano insieme (before tabs closed). Gli snapshot fissati non vengono mai cancellati.
La schermata di ripristino
Basta lanciare ai-tabs. A sinistra gli snapshot, a destra le tab dello snapshot
selezionato: per ogni tab, quale agente ci girava, in quale cartella e con quale
titolo. Dopo un riavvio la schermata parte già sull’ultimo snapshot prima del riavvio:
basta premere enter.

Il pallino verde segnala una sessione che gira ancora: ai-tabs non la riprende una seconda volta, perché due processi sullo stesso file di sessione lo corrompono. Per lo stesso motivo, se uno snapshot contiene la stessa sessione in due pannelli, la riprende solo nel primo. Le tab con un agente che gira già partono deselezionate.
Prima di aprire, ai-tabs chiede dove: in nuove finestre, con posizione e dimensioni salvate, oppure come nuove tab della finestra corrente.

Con d (dry run) si vedono i comandi esatti che il ripristino eseguirà, pannello per
pannello:

Il tema chiaro o scuro segue l’aspetto di macOS, e t lo cambia:

Il tasto ? mostra tutti i comandi della schermata:

Quattro agenti, un solo contratto
| Agente | Come trova la sessione | Come la riprende |
|---|---|---|
| Claude Code | ~/.claude/sessions/<pid>.json |
claude --resume <id> |
| omp | il file di sessione che il processo tiene aperto (lsof), oppure --resume <file> |
omp --resume <file> |
| opencode | --session <id>, oppure il database di opencode, in sola lettura |
opencode --session <id> |
| hermes | --resume <id>, oppure ~/.hermes/state.db, in sola lettura |
hermes chat --resume <id> |
Un dettaglio che ho scoperto solo usando il tool dopo un riavvio vero: omp tiene aperto il
file di sessione solo mentre scrive. Una sessione appena ripresa, senza nuovi messaggi,
era invisibile allo snapshot successivo. Ora ai-tabs legge il file anche da
omp --resume <file>, e ai-tabs doctor controlla proprio che ogni processo agente abbia
una sessione riconosciuta.
I flag di avvio (modello, modalità dei permessi, eccetera) passano attraverso una
allowlist: si ripetono solo le impostazioni, mai i prompt o i flag usa e getta, e il
valore di --api-key non viene mai salvato.
Non solo snapshot
-
Sessioni chiuse:
ai-tabs sessions(o il tastor) elenca le sessioni recenti che non girano più, anche quelle che nessuno snapshot ha visto, e le riprende una per una.
-
Layout con nome:
ai-tabs layout save shopsalva un set di tab fisso,llo riapre. I layout non scadono mai.
-
Storico e diagnosi:
ai-tabs historymostra gli snapshot con le modifiche e i pin,ai-tabs doctorcontrolla tutta l’installazione in un comando.

-
Backup: un backup al giorno con
VACUUM INTO.ai-tabs backup --restore DATAfa prima una copia di sicurezza del database corrente. -
Export Markdown: un file per snapshot, con un front matter YAML, comodo per chi tiene le note in Markdown (per esempio con Obsidian).
Configurazione: dove finisce cosa
Senza configurazione funziona già tutto: ai-tabs segue le cartelle standard XDG.
| Cosa | Dove (default) |
|---|---|
| Configurazione | ~/.config/ai-tabs/config.toml (oppure $XDG_CONFIG_HOME/ai-tabs/) |
| Database degli snapshot | ~/.local/share/ai-tabs/ai-tabs.sqlite (oppure $XDG_DATA_HOME/ai-tabs/) |
| Backup giornalieri | ~/.local/share/ai-tabs/backups/ |
| Export Markdown | ~/.local/share/ai-tabs/export/ |
| Log | ~/Library/Logs/ai-tabs.log |
| Agenti launchd | ~/Library/LaunchAgents/com.github.ai-tabs.snapshot.plist e …watch.plist |
Il file di configurazione contiene solo le impostazioni che cambi: tutto il resto prende
il default. ai-tabs config mostra ogni valore e da dove arriva (default, file o
environment):

| Impostazione | Default | Significato |
|---|---|---|
data_dir |
~/.local/share/ai-tabs |
cartella del database |
export_dir |
data_dir/export |
cartella degli export Markdown |
export_latest |
false |
riscrive export_dir/latest.md dopo ogni snapshot |
backup_dir |
data_dir/backups |
cartella dei backup |
backup_keep |
7 |
quanti backup giornalieri tenere |
history_days |
30 |
per quanti giorni tenere gli snapshot non fissati |
snapshot_interval |
300 |
secondi tra due snapshot dell’agente launchd |
splash |
true |
mostra il logo all’apertura della schermata |
theme |
auto |
auto (segue macOS), dark o light |
watch |
true |
snapshot quando una tab o una finestra si apre o si chiude |
Si cambiano con ai-tabs config set CHIAVE VALORE e ai-tabs config unset CHIAVE, oppure
dalla finestra delle impostazioni con il tasto o. Per data_dir vale anche la variabile
d’ambiente AI_TABS_DIR. Dopo un cambio di snapshot_interval o di watch serve
ai-tabs install.

Zero Waste, anche qui
Il database resta nella cartella dati locale, non in una cartella sincronizzata: un tool di sync (iCloud, Dropbox, git) può copiare un SQLite aperto e corrompere la copia. Se vuoi gli snapshot nelle tue note, usa l’export Markdown, che è solo testo. I database di opencode e hermes si aprono in sola lettura. Nessun servizio esterno, nessun dato che esce dalla macchina.
Tecnologia
| Componente | Tecnologia |
|---|---|
| Linguaggio | Python 3.15 (uv lo installa da solo) |
| CLI | Typer + Rich |
| Interfaccia | Textual |
| Terminale | Python API di iTerm2 |
| Dati | SQLite |
| Rilascio | GitHub Actions + PyPI Trusted Publishing |
Oltre 260 test, licenza MIT. Funziona solo con iTerm2 su macOS. Gli screenshot di questo post usano dati fittizi.
Dove trovarlo
- Codice e documentazione su GitHub: github.com/WaYdotNET/ai-tabs
- Pacchetto su PyPI: pypi.org/project/ai-tabs
Serve la Python API di iTerm2 attiva (Settings › General › Magic › Enable Python API).
Poi uv tool install ai-tabs, ai-tabs install e ai-tabs doctor. Issue e PR sono
benvenute.