Imported from mahendrakalkura/history-cleaner (
AGENTS.md). Install upstream withnpx skills add mahendrakalkura/history-cleaner. Copyright stays with the author.
AGENTS.md
Project Overview
history-cleaner is a single-binary Go CLI tool that selectively deletes browsing history by domain from Firefox, Chrome, or Chromium.
Architecture
Single-file application (main.go, ~480 lines). No packages, no interfaces.
Flow (6 screens)
- Browser select — detects installed browsers, user picks one
- Running check — exits if the chosen browser is open (checks multiple process names per browser)
- Profile select — picks profile (Firefox:
profiles.ini, Chrome/Chromium:Local StateJSON or glob fallback) - Date range input — user enters number of days to scan (default: 1)
- Domain select — multi-select of domains found in the date range, with visit counts
- Delete + report — deletes ALL history for selected domains across all time in a single transaction, shows deleted/remaining counts
Key functions
detectBrowsers()— checks for~/.mozilla/firefox/,~/.config/google-chrome/,~/.config/chromium/isRunning(processNames)—pgrep -xcheck against multiple process name variantsselectProfile(title, options)— shared UI helper for profile selection promptsfindFirefoxDB(configDir)— parsesprofiles.inifor profile selectionfindChromeDB(configDir, name)— parsesLocal StateJSON, falls back to globbing*/HistoryextractHost(rawURL)— returns hostname from URLescapeLike(s)— escapes%and_for safe SQL LIKE patternsqueryHosts(db, kind, cutoff)— queries recent history, returns domain→count mapdeleteHosts(db, kind, domains)— deletes visits + orphaned URLs in a transaction, returns deleted/remaining counts
Browser differences
| Firefox | Chrome/Chromium | |
|---|---|---|
| DB file | places.sqlite |
History |
| URL table | moz_places |
urls |
| Visit table | moz_historyvisits |
visits |
| Timestamp | Unix microseconds | Microseconds since 1601-01-01 |
| Profiles | profiles.ini |
Local State JSON |
| Orphan cleanup | foreign_count = 0 check |
Simple NOT IN check |
| Process names | firefox, firefox-esr |
chrome/google-chrome, chromium/chromium-browser |
Tech Stack
- Go 1.26 with CGO (required for sqlite3)
- charmbracelet/huh for terminal UI
- mattn/go-sqlite3 for SQLite access
- gopkg.in/ini.v1 for INI file parsing (Firefox profiles)
Build
make build # format, fetch deps, tidy, compile to ./main
make lint # golangci-lint
make test # run tests with coverage report
make run # build and run
make benchmarks # run benchmarks
Conventions
- All code in a single
main.go - No comments in the code
- Tests exist in main_test.go (unit tests, benchmarks, examples)
- Error handling: print to stderr and
os.Exit(1) - Use
huhforms for all interactive prompts - Linux-only (uses
pgrep, reads browser config from home dir) - Chromium reuses
browserChromekind (identical DB format) - Deletions are wrapped in a transaction with rollback on error
- WAL checkpoint is run after opening the database
- Always run
make build && make lintafter every code change — must have 0 lint issues
Gotchas
- Browser must be closed before running
- Date range input controls which domains are shown, but deletion removes ALL history for selected domains
extractHostreturns the full hostname, not just the registrable domain- Chrome timestamps use Windows epoch (1601-01-01), offset by
chromeEpochOffsetUsec - Domain matching uses two LIKE patterns (
%://domainand%://domain/%) to avoid substring false positives