Documentation
¶
Overview ¶
Package snapshot captures pre-write copies of Flipper SD files so /rewind can restore them on demand. Snapshots are small (SD files rarely exceed a few hundred KB) and are grouped per-session so the retention story is trivial: the next session doesn't see the previous session's undo history.
Layout under $SNAPSHOT_DIR/<session>/:
20260422T091530-abcdef.bak — the raw pre-write contents 20260422T091530-abcdef.json — metadata (original path, sha256)
The snapshot dir defaults to ~/.promptzero/snapshots but can be overridden at construction time for tests.
Index ¶
- Constants
- func DefaultRoot() (string, error)
- type Entry
- type Manager
- func (m *Manager) List(sessionID string) ([]Entry, error)
- func (m *Manager) Purge(sessionID string) error
- func (m *Manager) Restore(sessionID, id string) (Entry, []byte, error)
- func (m *Manager) Rotate(sessionID string, keep int) (int, error)
- func (m *Manager) Store(sessionID, originalPath string, content []byte) (Entry, error)
Constants ¶
const DefaultRetention = 100
DefaultRetention is the number of most-recent snapshots a session keeps when Rotate is called without an explicit value. Tuned for the typical pentest session (a few dozen write operations) with headroom — 100 entries at a mean of ~30 KB each is ~3 MB per session, trivial even on cramped SD cards. Longer sessions should Purge between phases or raise the keep value explicitly.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Entry ¶
type Entry struct {
ID string `json:"id"` // base filename without extension
OriginalPath string `json:"original_path"` // the Flipper path that was about to be overwritten
TakenAt time.Time `json:"taken_at"` // wall-clock at snapshot time
SizeBytes int `json:"size_bytes"` // byte length of the captured content
SHA256 string `json:"sha256"` // hex digest of the content
DataFile string `json:"-"` // absolute path to the .bak file (populated by List / Get)
}
Entry is the public metadata record for a saved snapshot. Exposed so /rewind list can render a table without re-parsing filenames.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager owns the on-disk snapshot tree and provides Store / List / Restore primitives keyed by session ID. Safe for concurrent use — each method takes no cross-request state and the filesystem handles atomicity via rename.
func NewManager ¶
NewManager constructs a Manager rooted at the given directory. The root is created lazily on the first Store call so passing a non-existent dir is not an error (important for tests using t.TempDir paths that may not survive between runs).
func (*Manager) List ¶
List returns every snapshot recorded under the given session, newest first. Session directories that don't exist yet return an empty slice (not an error) so UI can render "no snapshots" cleanly.
func (*Manager) Purge ¶
Purge removes every snapshot for a session. Intended for cleanup when a session is explicitly dropped; the per-session dir stays around on normal exit so /rewind still works across restarts.
func (*Manager) Restore ¶
Restore reads the raw pre-write content for a given snapshot ID. Returns an error if the ID doesn't exist — callers are expected to pair this with a Flipper write to the entry's OriginalPath.
func (*Manager) Rotate ¶ added in v0.3.1
Rotate trims the per-session snapshot tree down to the most recent 'keep' entries, deleting older .bak/.json pairs. Intended to run periodically (e.g. on session save, between workflow phases) so long-running sessions don't accumulate unbounded undo history.
A keep value of 0 or negative defaults to DefaultRetention. The newest entries (highest timestamp-prefixed IDs) are preserved. Nothing is deleted when the current count is at or below keep.
Returns the number of snapshots deleted. Missing session dirs are a no-op (returns 0, nil) — rotate is safe to call before any snapshots have landed.
func (*Manager) Store ¶
Store records a snapshot of the given path + content under the specified session. Returns the Entry so callers can log the ID for later reference. content is copied into the snapshot tree verbatim — no compression (SD files are tiny) and no encryption (if the SD card held secrets the operator already authorised the agent's reading it).