a local-first daemon

Write notes.Sloth commits them.

A tiny Go daemon that watches your markdown vault, debounces rapid edits, and asks a locally-running model to write the commit message. Your notes never leave your machine.

install
$ go install github.com/iamkorun/sloth/cmd/sloth@latest
100% local Works offline Single binary MIT licensed
ยง 01  ยท  the flow

Watch. Think locally. Commit.

Three small pieces, no surprises, no cloud round-trip. Here is the entire pipeline from your save to your git log.

i.

Watch the vault

A tiny fsnotify watcher catches every write, create, and rename in the directories you configured. Events are filtered through watch.exclude globs and an extension whitelist, so .git/, .obsidian/, swap files, and binary junk never make it into a batch.

ii.

Debounce rapid edits

The batcher waits for a quiet period โ€” 30 seconds by default โ€” so a fast save cycle in Obsidian becomes one logical commit, not thirty. A hard ceiling (max_wait_seconds) prevents a chatty editor from starving the batch forever.

iii.

Commit โ€” with a message from your own machine

Sloth runs git add -A, captures the diff, trims it at max_diff_bytes, and asks a local Ollama model โ€” Mistral, Llama, Phi, whatever you pulled โ€” to write a conventional-commits subject line. No API key, no round-trip, no egress. If Ollama is unreachable, the fallback message is used and the commit still happens.

ยง 02  ยท  configure

One small TOML file. No surprises.

Run sloth init once. It writes this to ~/.config/sloth/config.toml. Edit to taste.

Every knob has a sensible default and a short comment. Point watch.paths at your vault, set ollama.model to whatever you pulled with ollama pull, and you're done.

The debounce window is the single most useful dial. Crank it up for a journal that you write in long sittings; crank it down if you want near-real-time commits as you type.

If Ollama is down or slow, fallback_message takes over. Sloth never blocks on the model.

~/.config/sloth/config.toml
[watch]
paths      = ["~/notes"]
exclude    = [".git/**", ".obsidian/**", "*.tmp"]
extensions = [".md", ".txt"]

[debounce]
# quiet period before a batch fires
window_seconds   = 30
# hard ceiling so a chatty loop can't starve the batch
max_wait_seconds = 300

[ollama]
endpoint         = "http://localhost:11434"
model            = "mistral"
timeout_seconds  = 30
fallback_message = "chore: auto-commit notes"
max_diff_bytes   = 4096

[git]
author_name   = ""   # falls back to git config
author_email  = ""
commit_prefix = ""   # optional "[notes] " prefix

[log]
level = "info"
ยง 03  ยท  the whole point

Every other "smart commit" tool quietly ships your diff to somebody else's GPU. Sloth doesn't. Your notes, your diff, your commit message โ€” they stay on the machine you're typing on, every time, even on a plane with the wifi switch off.

no API keys no network egress no telemetry no cloud dependencies no vendor lock-in
ยง 04  ยท  questions

The usual asks.

What if Ollama isn't running?

Commits still happen โ€” they just use ollama.fallback_message instead of an LLM-generated one. Sloth never blocks on the model, so a dead GPU never costs you a commit.

Can I use a different model?

Any Ollama model. Set ollama.model = "llama3.2" (or qwen2.5, phi3, gemmaโ€ฆ) in the config. Smaller and faster is fine โ€” the prompt is tiny.

Does it commit binary files or leak secrets?

Sloth only reacts to files matching watch.extensions (default: .md, .txt). Binaries never trigger a batch. max_diff_bytes truncates the diff before it's shown to the model, so even a long paste can't run away.

Will it ever force-push or rewrite history?

No. Sloth only git add -A and git commit. It never pushes, never rebases, never amends, never touches a remote. Pushing is your job โ€” sloth just keeps the local log honest.

Does this work on systemd?

Yes. A user-mode unit ships in contrib/sloth.service. systemctl --user enable --now sloth and you're done. SIGTERM is handled gracefully โ€” any pending batch is flushed before exit.

ยง 05  ยท  start

Let your notes commit themselves.

$ go install github.com/iamkorun/sloth/cmd/sloth@latest
Copied to clipboard