ai-tabs: le tab di iTerm2 e le sessioni degli agenti AI sopravvivono al riavvio

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 tasto r) 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 shop salva un set di tab fisso, l lo riapre. I layout non scadono mai.

  • Storico e diagnosi: ai-tabs history mostra gli snapshot con le modifiche e i pin, ai-tabs doctor controlla tutta l’installazione in un comando.

  • Backup: un backup al giorno con VACUUM INTO. ai-tabs backup --restore DATA fa 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

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.