saferm v0.2.0
On this page

saferm is an AI-first safe rm replacement that archives files instead of permanently deleting them, with rich metadata capture and full undo support.

#saferm

AI-first safe rm replacement. Archives files instead of deleting them.

#CLI Reference

#Packages

#internal/archive

Package archive handles file and directory archival to the saferm archive. It supports atomic same-filesystem renames, cross-device copy-and-verify, and tar+zstd compression for directories.

#ErrFileNotFound

Go go
var ErrFileNotFound     = errors.New("file not found")

Sentinel errors.

#ErrRecursiveRequired

Go go
var ErrRecursiveRequired = errors.New("target is a directory; recursive flag required")

#ErrConflict

Go go
var ErrConflict         = errors.New("destination already exists")

#ErrHashMismatch

Go go
var ErrHashMismatch     = errors.New("hash mismatch after copy")

#ArchiveResult

Go go
type ArchiveResult struct

ArchiveResult holds the outcome of archiving a file or directory.

#Archive

Go go
func Archive(path string, archiveDir string, isRecursive bool) (*ArchiveResult, error)

Archive moves a file or directory into archiveDir, returning the result. For files: moved directly (or copied cross-device) with SHA-256 hash. For directories: compressed into a .tar.zst archive.

#Restore

Go go
func Restore(uuid string, archiveDir string, destPath string, isDirectory bool, force bool) error

Restore extracts an archived file or directory to destPath.

#internal/db

Package db manages the SQLite database tracking all saferm deletions. It uses WAL mode and busy_timeout for concurrency safety across multiple simultaneous sessions.

#SchemaSQL

Go go
const SchemaSQL = `

#ErrNotFound

Go go
var ErrNotFound = errors.New("record not found")

ErrNotFound is returned when a queried record does not exist.

#DB

Go go
type DB struct

DB wraps a *sql.DB connection to the saferm SQLite database.

#DeletionRecord

Go go
type DeletionRecord struct

DeletionRecord represents a single archived deletion in the database.

#Open

Go go
func Open(dbPath string) (*DB, error)

Open opens (or creates) the SQLite database at dbPath with WAL mode and busy_timeout=5000ms, then runs the schema DDL.

#DB.Close

Go go
func (d *DB) Close() error

Close closes the underlying database connection.

#DB.Insert

Go go
func (d *DB) Insert(rec *DeletionRecord) (int64, error)

Insert inserts a DeletionRecord and returns the auto-increment ID.

#DB.QueryByID

Go go
func (d *DB) QueryByID(id int64) (*DeletionRecord, error)

QueryByID retrieves a single record by ID. Returns ErrNotFound if it does not exist.

#DB.QueryByPath

Go go
func (d *DB) QueryByPath(path string) ([]*DeletionRecord, error)

QueryByPath returns all non-restored records matching the given original_path, ordered by deleted_at DESC (newest first).

#DB.QueryAll

Go go
func (d *DB) QueryAll(includeRestored bool) ([]*DeletionRecord, error)

QueryAll returns all records ordered by deleted_at DESC. If includeRestored is false, restored records are excluded.

#DB.MarkRestored

Go go
func (d *DB) MarkRestored(id int64, restoredTo string) error

MarkRestored sets restored_at to now and restored_to to the given path. Returns ErrNotFound if the record does not exist.

#DB.Delete

Go go
func (d *DB) Delete(id int64) error

Delete permanently removes a record by ID (used for purge). Returns ErrNotFound if the record does not exist.

#DB.QueryOlderThan

Go go
func (d *DB) QueryOlderThan(before time.Time) ([]*DeletionRecord, error)

QueryOlderThan returns all non-restored records deleted before the given time.

#internal/git

Package git provides helpers for managing the git index alongside saferm's archive/restore operations.

#IsInGitRepo

Go go
func IsInGitRepo(dir string) bool

IsInGitRepo returns true if dir is inside a git working tree.

#IsGitTracked

Go go
func IsGitTracked(path string) bool

IsGitTracked returns true if the file at path is tracked by git (i.e., known to the index). The path must be absolute or relative to the current working directory; the command runs from the file's parent directory.

#GitRmCached

Go go
func GitRmCached(path string, recursive bool) error

GitRmCached stages the removal of path in the git index without touching the working tree (the file is already archived). When recursive is true, -r is added for directory removal.

#GitAdd

Go go
func GitAdd(path string) error

GitAdd stages a file in the git index. The command runs from the file's parent directory.

#internal/meta

Package meta collects rich metadata about each deletion: environment variables, git repository context, parent process information, and arbitrary user-supplied key-value pairs.

#Metadata

Go go
type Metadata struct

Metadata holds contextual information captured at deletion time.

#Collect

Go go
func Collect(cfg *config.Config, customMeta map[string]string) (*Metadata, error)

Collect gathers metadata from the current environment. Never fails fatally -- if a collector errors, it populates what it can.

#internal/config

Package config manages saferm's TOML configuration and directory initialization. Configuration is loaded from ~/.saferm/config.toml with sensible defaults when the file is absent.

#Config

Go go
type Config struct

Config holds saferm configuration, loaded from TOML.

#BaseDir

Go go
func BaseDir() string

BaseDir returns the saferm base directory. If SAFERM_HOME is set, its value is used as-is (expected to be an absolute path). Otherwise falls back to ~/.saferm/.

#DefaultConfig

Go go
func DefaultConfig() *Config

DefaultConfig returns a Config with all defaults filled in.

#Load

Go go
func Load() (*Config, error)

Load reads the config file from the default location (~/.saferm/config.toml) and returns a Config with defaults applied. If the file doesn't exist, returns the default config without error.

#LoadFrom

Go go
func LoadFrom(path string) (*Config, error)

LoadFrom reads config from the specified path. If the file doesn't exist, returns the default config without error. If it exists but is malformed, returns an error.

#EnsureDirectories

Go go
func EnsureDirectories(cfg *Config) error

EnsureDirectories creates the archive dir, db dir (parent of DBPath), and base dir if they don't exist. Uses 0700 permissions.