Show HN: Unfucked - version all changes (by any tool) - local-first/source avail (unfudged.io)

137 points by cyrusradfar ↗ HN
I built unf after I pasted a prompt into the wrong agent terminal and it overwrote hours of hand-edits across a handful of files. Git couldn't help because I hadn't finished/committed my in progress work. I wanted something that recorded every save automatically so I could rewind to any point in time. I wanted to make it difficult for an agent to permanently screw anything up, even with an errant rm -rf

unf is a background daemon that watches directories you choose (via CLI) and snapshots every text file on save. It stores file contents in an object store, tracks metadata in SQLite, and gives you a CLI to query and restore any version. The install includes a UI, as well to explore the history through time.

The tool skips binaries and respects `.gitignore` if one exists. The interface borrows from git so it should feel familiar: unf log, unf diff, unf restore.

I say "UN-EF" vs U.N.F, but that's for y'all to decide: I started by calling the project Unfucked and got unfucked.ai, which if you know me and the messes I get myself into, is a fitting purchase.

The CLI command is `unf` and the Tauri desktop app is titled "Unfudged" (kids safe name).

How it works: https://unfucked.ai/tech (summary below)

The daemon uses FSEvents on macOS and inotify on Linux. When a file changes, `unf` hashes the content with BLAKE3 and checks whether that hash already exists in the object store — if it does, it just records a new metadata entry pointing to the existing blob. If not, it writes the blob and records the entry. Each snapshot is a row in SQLite. Restores read the blob back from the object store and overwrite the file, after taking a safety snapshot of the current state first (so restoring is itself reversible).

There are two processes. The core daemon does the real work of managing FSEvents/inotify subscriptions across multiple watched directories and writing snapshots. A sentinel watchdog supervises it, kept alive and aligned by launchd on macOS and systemd on Linux. If the daemon crashes, the sentinel respawns it and reconciles any drift between what you asked to watch and what's actually being watched. It was hard to build the second daemon because it felt like conceding that the core wasn't solid enough, but I didn't want to ship a tool that demanded perfection to deliver on the product promise, so the sentinel is the safety net.

Fingers crossed, I haven’t seen it crash in over a week of personal usage on my Mac. But, I don't want to trigger "works for me" trauma.

The part I like most: On the UI, I enjoy viewing files through time. You can select a time section and filter your projects on a histogram of activity. That has been invaluable in seeing what the agent was doing.

On the CLI, the commands are composable. Everything outputs to stdout so you can pipe it into whatever you want. I use these regularly and AI agents are better with the tool than I am:

  # What did my config look like before we broke it?
  unf cat nginx.conf --at 1h | nginx -t -c /dev/stdin

  # Grep through a deleted file
  unf cat old-routes.rs --at 2d | grep "pub fn"

  # Count how many lines changed in the last 10 minutes
  unf diff --at 10m | grep '^[+-]' | wc -l

  # Feed the last hour of changes to an AI for review
  unf diff --at 1h | pbcopy

  # Compare two points in time with your own diff tool
  diff <(unf cat app.tsx --at 1h) <(unf cat app.tsx --at 5m)

  # Restore just the .rs files that changed in the last 5 minutes
  unf diff --at 5m --json | jq -r '.changes[].file' | grep '\.rs$' | xargs -I{} unf restore {} --at 5m

  # Watch for changes in real time
  watch -n5 'unf diff --at 30s'
What was new for me: I came to Rust in Nov. 2025 honestly because of HN enthusiasm and some FOMO. No regrets. I enjoy the language enough that I&#x...

35 comments

[ 0.29 ms ] story [ 53.3 ms ] thread
(comment deleted)
this seems insanely useful and well thought out. kinda surprised something like it doesn’t already exist. def useful in the age of agents
Yep, I’ve needed something like this a few times. Even when trying to be careful to commit every step to a feature branch, I’ve still found myself asking for code fixes or updates in a single iteration and kicking myself when I didn’t just commit the damn thing. This will be a nice safety net.
why did you make it so complicated? magit has a `magit-wip-mode` that just silently creates refs in git intermittently so you can just use the reflog to get things back.
This is so cool to have made yourself. How would you compare this to the functionality offered by jujutsu? I love the histogram, it was the first sort of thing I wanted out of jujutsu that its UI doesn't make very easy. But with jj the filesystem tracking is built in, which is a huge advantage.
One of the uses cases on their website is the agent deleted my .env file.

jj wouldn’t help with that as it would be gitignored.

FYI all Jetbrains IDEs include this, as long as they are open on the codebase. It's called "Local history".
I love the website; the design, the video, the NSFW toggle, the simplicity.

I love the idea; definitely something I ran into a few times before and wish I had.

Unfortunately, I am not installing a closed-source daemon with access to the filesystem from an unknown (to me) developer. I will bookmark this and revisit in a few weeks and hope you had published the source. :)

I have used fossil in a similar way, also local, and sqlite based. Admittedly you have to add files to it first but setting it running via cron was simple enough. Though it wasn't be ause I let an AI access all my stuff.
Where is the source? I'm not going to rely on or trust anything this important to code I can't read.
love the idea of this, but echoing others... closed source daemon with access to all files is a 100% non-starter.
This would be great as aVSCode(ium) extension.
OP here --

I could build an extension for the UI vs a Tauri app, and it could help you install the CLI if you don't have it. Would that meet your needs?

That said, the fidelity of OS-level daemon can't really be replicated from within an app process.

So this is Time Machine, but with extra steps? </s>
Excellent idea. Looking forward to trying it. Any way to install it without brew?
Why not just fuckin commit!?
This is not something I would ever use. The idea of giving a probabilistic model the permission to run commands with full access to my filesystem, and at the very least not reviewing and approving everything it does, is bonkers to me.

But I'm amused by the people asking for the source code. You trust a tool from a giant corporation with not only your local data, but with all your data on external services as well, yet trusting a single developer with a fraction of this is a concern? (:

ZFS snapshots can be used to similar effect, basically for free.