$
+====[ THE MISTAKE ]====+
$ rm -rf /important-project
removing ./src/index.ts
removing ./src/components/App.tsx
removing ./src/utils/helpers.ts
removing ./package.json
removing ./tsconfig.json
removing ./README.md
removing ./.git/HEAD
removing ./.env.production
fatal: 247 files permanently deleted.
    ╔══════════════════════╗
    ║   ⚠  DATA  LOST  ⚠  ║
    ╚══════════════════════╝
+====[ THE UNDO ]====+
$ undo --restore /important-project
restored ./.env.production
restored ./.git/HEAD
restored ./README.md
restored ./tsconfig.json
restored ./package.json
restored ./src/utils/helpers.ts
restored ./src/components/App.tsx
restored ./src/index.ts
Done. 247 files restored. Nothing was lost.
+====[ THE PHILOSOPHY ]====+
$ undo --explain "why"

Every action leaves a trace

The filesystem remembers what you forget. undo.sh intercepts destructive operations before they become irreversible, maintaining a shadow ledger of every change. Not a backup — a timeline.

$ undo --explain "how"

Reversibility as a first principle

Instead of preventing mistakes, we make them inconsequential. Move fast, break things, then un-break them. The safety net exists so you never have to hesitate before pressing enter.

$ undo --explain "what-if"

Time is not an arrow

In the terminal, time flows in both directions. Every rm has its restore, every push --force its reflog. We merely formalize what the universe of version control already knows: nothing is truly gone.

$ undo --version

undo.sh v∞.0.0 — because finality is a bug, not a feature.

$ exit

Session ended. Nothing was lost.

undo.sh