Oyster uses two separately owned data domains:
~/.pi/agent/sessions.sqlite~/.pi/agent/oyster.sqliteNever replace one with the other.
SQLite uses WAL mode. Use SQLite's backup API while writers are active:
1 2 3 4 5 6 7mkdir -p "$HOME/pi-backups" node --input-type=module -e ' import { DatabaseSync, backup } from "node:sqlite"; const source = new DatabaseSync(`${process.env.HOME}/.pi/agent/sessions.sqlite`, { readOnly: true }); await backup(source, `${process.env.HOME}/pi-backups/sessions.sqlite`); source.close(); '
Stop the service before copying a database as files. Copy the main file and every existing -wal and -shm sidecar as one snapshot.
1 2 3 4 5systemctl --user stop pi-ui.service for file in "$HOME/.pi/agent/sessions.sqlite"{,-wal,-shm}; do test ! -e "$file" || cp --preserve "$file" "$HOME/pi-backups/" done systemctl --user start pi-ui.service
Apply the same closed-database rule to oyster.sqlite.
/health, sessions, routines, and hublots.