Skip to content
InfantAjayVenusPublic

About

This is a drop-in wrapper over `rm` command in Unix systems with System trash integration to play safe with AI/self.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

trash-rm

trash-rm is a Go CLI that wraps rm with trash-first behavior.

Instead of deleting files immediately, it first sends them to the system trash, writes a sidecar history entry, and then calls the real system rm. It is intended to be installed as trash-rm plus an rm -> trash-rm symlink so normal rm usage is transparently protected.

What It Does

  • Moves file targets to the system trash before invoking the real rm
  • Supports a bypass flag: --be-brave-skip-trash
  • Records trash operations in a local history file
  • Provides --restore to browse previous trash entries in an interactive TUI and restore them
  • Resolves the real rm from /bin/rm or /usr/bin/rm to avoid symlink recursion

Platform Support

Linux

  • Trash backend: trash from trash-cli
  • Restore backend: trash-list and trash-restore
  • History file: ~/.local/share/trash-rm/history.json

macOS

  • Trash backend: osascript via Finder
  • History file: ~/Library/Application Support/trash-rm/history.json

Current implementation note: the restore path is written around trash-list and trash-restore, so trashing on macOS is implemented, but restore appears Linux-oriented in the current codebase.

CLI

trash-rm [rm-flags] <files>...
trash-rm --be-brave-skip-trash [rm-flags] <files>...
trash-rm --restore

# after install.sh creates the symlink
rm [rm-flags] <files>...

Behavior

Normal delete flow

  1. Parse CLI args.
  2. Check the platform trash dependency.
  3. Move each file to trash.
  4. Append one NDJSON history entry.
  5. Call the real rm.

If trashing fails:

  • In an interactive terminal, the tool prompts: Unable to trash before delete. Proceed without trash protection? [y/N]
  • In a non-interactive context, it aborts automatically without prompting.

A session is considered non-interactive when any of the following is true:

  • stdin is not a terminal (e.g. piped input)
  • stdout is not a terminal (e.g. rm foo > file)
  • stderr is not a terminal (e.g. rm foo 2>/dev/null)
  • the CI environment variable is set to "true" (GitHub Actions, GitLab CI, CircleCI, etc.)
  • If the user declines, it aborts.
  • If the user confirms, it skips history logging and runs the real rm.

If writing the history log fails, it aborts and does not invoke rm.

Skip-trash mode

--be-brave-skip-trash bypasses trash and logging entirely and forwards the rest of the arguments to the real rm.

Restore mode

--restore:

  • Reads the history log
  • Cross-references entries against trash-list
  • Shows remaining entries in a Bubble Tea TUI
  • Restores the selected entry
  • Rewrites the history file without the restored entry

If no usable history exists, it prints:

No trash history found.

History Format

History is stored as newline-delimited JSON:

{"timestamp":"2026-03-17T14:05:00Z","command":"trash-rm -rf old-project","cwd":"/home/user/projects","files":["old-project"]}

Fields:

  • timestamp: RFC 3339 UTC timestamp
  • command: reconstructed command string
  • cwd: working directory at deletion time
  • files: file operands that were trashed

Install

Quick install

./install.sh

By default this:

  • Builds trash-rm
  • Installs it to /usr/local/bin/trash-rm
  • Creates /usr/local/bin/rm -> trash-rm

You can override the install directory:

INSTALL_DIR="$HOME/.local/bin" ./install.sh

Linux dependency

Install trash-cli before use:

sudo apt install trash-cli
# or
sudo dnf install trash-cli

The installer warns if the backend dependency is missing.

Development

Repo layout:

Open Issues

# Issue Kind
1 macOS --restore not implemented — the restore flow (FilterAlive, RestoreEntry) relies on trash-list and trash-restore from trash-cli, which is Linux-only. Files trashed on macOS via osascript cannot be restored through --restore until a macOS-native restore backend is added. Bug / missing feature
2 args.Parse returns its own "missing file operand" error instead of delegating that case to native rm. The error text matches what rm would print, but the exit behaviour is handled by trash-rm rather than the real rm. Minor behavioural gap
3 Flag parser is intentionally simple — any token starting with - is forwarded as an rm flag; any other token is treated as a file operand. Combined flags such as -rf are passed through correctly, but the parser does not validate rm-flag semantics. By design / known limitation

Status

The repo includes unit tests across all internal packages (go test ./... passes). All six TDD slices are implemented.

About

This is a drop-in wrapper over `rm` command in Unix systems with System trash integration to play safe with AI/self.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages