
Browser History
- 46 installs
- 14 repo stars
- Updated July 28, 2026
- samhvw8/dotfiles
Helps with ai & agent building tasks.
About
browser-history is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- browser-history
- AI & Agent Building
- AI-coding skill
Browser History by the numbers
- 46 all-time installs (skills.sh)
- Ranked #7,539 of 16,556 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/samhvw8/dotfiles --skill browser-historyAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 46 |
|---|---|
| repo stars | ★ 14 |
| Last updated | July 28, 2026 |
| Repository | samhvw8/dotfiles ↗ |
What it does
Helps with ai & agent building tasks.
Files
Browser History Search
Search the user's browser history to find visited pages, analyze browsing patterns, and retrieve forgotten information.
When to use
- User asks about pages they visited ("what github repos did I look at last week?")
- User wants to find a forgotten page ("find that article about LLMs I read")
- User asks about browsing habits ("how much time did I spend on Twitter?")
- User wants browsing statistics ("show my most visited sites")
Requirements
sqlite3CLI
Setup
First, detect available browsers by running:
./find-browser.sh- Output: PATH,TYPE,BROWSER,LAST_MODIFIED
- TYPE:
firefoxorchromium(determines SQL syntax) - Use the first result (most recently used browser) by default
- If multiple browsers were used recently (within last 24h), ask the user which one to search
Querying the database
Use ?immutable=1 in the SQLite URI to read the database even when the browser is open:
sqlite3 "file:///path/to/history.db?immutable=1" "SELECT ..."Firefox databases (places.sqlite)
Search by keyword:
SELECT
title,
url,
datetime(last_visit_date/1000000, 'unixepoch', 'localtime') as visit_date
FROM moz_places
WHERE url LIKE '%keyword%' OR title LIKE '%keyword%'
ORDER BY last_visit_date DESC
LIMIT 50;Search by date range:
SELECT url, title, datetime(last_visit_date/1000000, 'unixepoch', 'localtime') as visit_date
FROM moz_places
WHERE last_visit_date > strftime('%s', '2025-01-01') * 1000000
AND last_visit_date < strftime('%s', '2025-01-31') * 1000000
ORDER BY last_visit_date DESC;Time spent analysis (uses moz_places_metadata):
SELECT
SUM(m.total_view_time) / 1000 / 60 as minutes,
COUNT(*) as sessions
FROM moz_places_metadata m
JOIN moz_places p ON m.place_id = p.id
WHERE p.url LIKE '%example.com%'
AND m.created_at > strftime('%s', '2025-01-01') * 1000;Note: created_at is in milliseconds, last_visit_date is in microseconds.
Most visited sites:
SELECT
SUBSTR(url, INSTR(url, '://') + 3,
INSTR(SUBSTR(url, INSTR(url, '://') + 3), '/') - 1) as domain,
SUM(visit_count) as visits
FROM moz_places
WHERE url LIKE 'http%'
GROUP BY domain
ORDER BY visits DESC
LIMIT 20;Chromium databases (History)
Important: Chromium timestamps are microseconds since January 1, 1601 (Windows epoch).
Conversion: (timestamp/1000000) - 11644473600 gives Unix epoch.
Search by keyword:
SELECT
title,
url,
datetime((last_visit_time/1000000)-11644473600, 'unixepoch', 'localtime') as visit_date
FROM urls
WHERE url LIKE '%keyword%' OR title LIKE '%keyword%'
ORDER BY last_visit_time DESC
LIMIT 50;Search by date range:
SELECT url, title, datetime((last_visit_time/1000000)-11644473600, 'unixepoch', 'localtime') as visit_date
FROM urls
WHERE last_visit_time > (strftime('%s', '2025-01-01') + 11644473600) * 1000000
AND last_visit_time < (strftime('%s', '2025-01-31') + 11644473600) * 1000000
ORDER BY last_visit_time DESC;Database schema
Firefox (moz_places)
| Column | Description |
|---|---|
url | Full URL |
title | Page title |
last_visit_date | Microseconds since Unix epoch |
visit_count | Number of visits |
frecency | Frequency + recency score |
Firefox (moz_places_metadata)
| Column | Description |
|---|---|
place_id | Foreign key to moz_places |
total_view_time | Milliseconds spent on page |
created_at | Milliseconds since Unix epoch |
scrolling_time | Time spent scrolling |
key_presses | Number of key presses |
Chromium (urls)
| Column | Description |
|---|---|
url | Full URL |
title | Page title |
last_visit_time | Microseconds since 1601-01-01 |
visit_count | Number of visits |
Output guidelines
- Present results in a readable format, grouped by domain when relevant
- For time analysis, show hours/minutes, not raw milliseconds
- When showing history, include the date and a clickable link
- If results are numerous, summarize by domain or time period
- You might include a small ASCII/Unicode chart (daily breakdown, histogram) if relevant
See @README.md for output examples.
#!/bin/bash
#
# find-browser.sh - Detect all browsers and their history databases
#
# Output format (tab-separated, sorted by most recent first):
# PATH<tab>TYPE<tab>BROWSER_NAME<tab>MTIME_HUMAN
#
# TYPE is either "firefox" or "chromium" (determines SQL syntax)
# Exit code 1 if no browser found
set -e
case "$(uname -s)" in
Darwin)
FIREFOX_BASE="$HOME/Library/Application Support"
CHROMIUM_BASE="$HOME/Library/Application Support"
stat_mtime() { stat -f "%m" "$1"; }
format_date() { date -r "$1" "+%Y-%m-%d %H:%M"; }
;;
Linux)
FIREFOX_BASE="$HOME"
CHROMIUM_BASE="$HOME/.config"
stat_mtime() { stat -c "%Y" "$1"; }
format_date() { date -d "@$1" "+%Y-%m-%d %H:%M"; }
;;
MINGW*|MSYS*|CYGWIN*)
FIREFOX_BASE="$APPDATA"
CHROMIUM_BASE="$LOCALAPPDATA"
stat_mtime() { stat -c "%Y" "$1"; }
format_date() { date -d "@$1" "+%Y-%m-%d %H:%M"; }
;;
*)
echo "Unsupported OS" >&2
exit 1
;;
esac
# Browser definitions: name|type|subpath (relative to base)
# Use F: prefix for Firefox base, C: for Chromium base
case "$(uname -s)" in
Darwin) BROWSERS="
Zen|firefox|F:zen/Profiles
Firefox|firefox|F:Firefox/Profiles
LibreWolf|firefox|F:LibreWolf/Profiles
Waterfox|firefox|F:Waterfox/Profiles
Chrome|chromium|C:Google/Chrome
Chromium|chromium|C:Chromium
Brave|chromium|C:BraveSoftware/Brave-Browser
Edge|chromium|C:Microsoft Edge
Arc|chromium|C:Arc/User Data
Vivaldi|chromium|C:Vivaldi
Opera|chromium|C:com.operasoftware.Opera
" ;;
Linux) BROWSERS="
Zen|firefox|F:.zen
Firefox|firefox|F:.mozilla/firefox
LibreWolf|firefox|F:.librewolf
Waterfox|firefox|F:.waterfox
Chrome|chromium|C:google-chrome
Chromium|chromium|C:chromium
Brave|chromium|C:BraveSoftware/Brave-Browser
Edge|chromium|C:microsoft-edge
Vivaldi|chromium|C:vivaldi
Opera|chromium|C:opera
" ;;
MINGW*|MSYS*|CYGWIN*) BROWSERS="
Firefox|firefox|F:Mozilla/Firefox/Profiles
LibreWolf|firefox|F:LibreWolf/Profiles
Waterfox|firefox|F:Waterfox/Profiles
Chrome|chromium|C:Google/Chrome/User Data
Chromium|chromium|C:Chromium/User Data
Brave|chromium|C:BraveSoftware/Brave-Browser/User Data
Edge|chromium|C:Microsoft/Edge/User Data
Vivaldi|chromium|C:Vivaldi/User Data
Opera|chromium|C:Opera Software/Opera Stable
" ;;
esac
output_file() {
local file="$1" type="$2" name="$3"
local mtime mtime_human
mtime=$(stat_mtime "$file")
mtime_human=$(format_date "$mtime")
printf "%s\t%s\t%s\t%s\t%s\n" "$mtime" "$file" "$type" "$name" "$mtime_human"
}
results=$(mktemp)
trap "rm -f $results" EXIT
echo "$BROWSERS" | while IFS='|' read -r name type path_spec; do
[[ -z "$name" ]] && continue
# Parse base prefix and subpath
base_type="${path_spec%%:*}"
subpath="${path_spec#*:}"
[[ "$base_type" == "F" ]] && base="$FIREFOX_BASE" || base="$CHROMIUM_BASE"
full_base="$base/$subpath"
[[ -d "$full_base" ]] || continue
# Firefox stores history in places.sqlite, Chromium in History
[[ "$type" == "firefox" ]] && filename="places.sqlite" || filename="History"
find "$full_base" -maxdepth 2 -name "$filename" -type f 2>/dev/null | while read -r file; do
output_file "$file" "$type" "$name"
done
done | sort -t$'\t' -k1 -rn | cut -f2- > "$results"
if [[ -s "$results" ]]; then
cat "$results"
else
echo "No browser history found" >&2
exit 1
fi